Автозаполнение пользовательского интерфейса jQuery не обновляет ngModel - PullRequest
0 голосов
/ 17 декабря 2018

Я пытаюсь использовать автозаполнение jquery ui, чтобы вставить значение в форму angularjs.Проблема в том, что когда я отправляю данные с $ http, значение, полученное при автозаполнении, не обновляет ng-модель!Я прочитал некоторый пост об использовании $ scope.apply (), но я не понимаю, как его использовать и где!Это код jquery для автозаполнения:

$(document).ready(function(){
        $("#tags").autocomplete({
             source: '/contabilita/include/autocomplete.asp',
             minChars: 3,
             autoFill: true,
             mustMatch:false,
             cacheLength: 1,
             select: function(event, ui) {
                event.preventDefault();
                $("#tags").val(ui.item.label);
                $("#selected-tags").val(ui.item.label);
                $("#PIVA").val(ui.item.piva);
                $("#CFISCA").val(ui.item.cf);
                $("#CAP").val(ui.item.cap);
                $("#CITY").val(ui.item.city);
                $("#INDIRIZZO").val(ui.item.indi).trigger('change');
                $("#INDIRIZZO").trigger('input');
                $("#PR").val(ui.item.pr).closest('.select-wrapper')
                .find('li').removeClass("active").closest('.select-wrapper')
                .find('.select-dropdown').val(ui.item.pr)
                .find('span:contains(' + ui.item.pr + ')')
                .parent().addClass('selected active');
                $("#PR").select();
            },
        });

И это HTML:

    <div class="row">
        <div class="col s1">
          <label>N°:
            <input type="text" ng-model="reg.NUMERO">
          </label>
        </div>
        <div class="col s5">
          <label>Intestazione:
            <input ng-model="reg.INTESTAZIONE" id="tags" type="text">
          </label>
        </div>
<div class="row">
        <div class="col s4">
          <label>Indirizzo:
            <input ng-model="reg.INDIRIZZO" id="INDIRIZZO" type="text" ng-model-options="{updateOn: 'change input'}">
          </label>
        </div>
        <div class="col s3">
          <label>Città:
            <input ng-model="reg.CITY" id="CITY" type="text">
          </label>
        </div>
        <div class="col s3">
          <label>CAP:
            <input ng-model="reg.CAP" id="CAP" type="text">
          </label>
        </div>

Это угловой контроллер:

    .controller('gestFat', function($scope,$http,$location,$rootScope) {
    $scope.reg = {};
    $scope.reg.GIORNO = $rootScope.today;
    $scope.reg.RF = "RF01";
    $scope.reg.T_IVA = "10";
    console.log("cerco la fattura");
    var com = $location.search().COM_ID;


    $scope.stampaFat = function(){
            $http.post('/contabilita/include/insert_fattura.php', $scope.reg)
            .success(function(data){
                M.toast({html:'Intervento inserito...'+data, inDuration:1500});
                })
            .error(function(status){alert("Errore di connessione!" + status)});

    };
})

РЕШЕНИЕ:

это окончательное решение

.directive('ngautocomplete', function () {
return function link(scope, element, attributes) {
    element.autocomplete({
        source: '/contabilita/include/autocomplete.asp',
         minChars: 3,
         autoFill: true,
         mustMatch:false,
         cacheLength: 1,
         select: function(event, ui) {
            event.preventDefault();
                $("#tags").val(ui.item.label);
                $("#PIVA").val(ui.item.piva).trigger('input');;
                $("#CFISCA").val(ui.item.cf).trigger('input');;
                $("#CAP").val(ui.item.cap).trigger('input');;
                $("#CD").val(ui.item.cd).trigger('input');;
                $("#PEC").val(ui.item.pec).trigger('input');;
                $("#CITY").val(ui.item.city).trigger('input');;
                $("#INDIRIZZO").val(ui.item.indi).trigger('input');
                $("#NAZIONE").val(ui.item.nazione).closest('.select-wrapper').find('li').removeClass("active").closest('.select-wrapper').find('.select-dropdown').val(ui.item.nazione).find('span:contains(' + ui.item.nazione + ')').parent().addClass('selected active');
                $("#NAZIONE").select().trigger('change');;
                $("#PR").val(ui.item.pr).closest('.select-wrapper').find('li').removeClass("active").closest('.select-wrapper').find('.select-dropdown').val(ui.item.pr).find('span:contains(' + ui.item.pr + ')').parent().addClass('selected active');
                $("#PR").select().trigger('change');;
            }
            });
};

})

Ответы [ 3 ]

0 голосов
/ 17 декабря 2018

Вы должны заключить автозаполнение в директиву, потому что я вижу, что оно вносит много изменений в пользовательский интерфейс за пределами приложения angular, и я думаю, что многие из этих изменений влияют на html, генерируемый angular.

    angular.directive(‘gest-fat-autocomplete’, function() {
        return {
            require: 'ngModel',
            controller: function($http, $location, $rootScope) {
                this.reg = {};
                this.reg.GIORNO = $rootScope.today;
                this.reg.RF = "RF01";
                this.reg.T_IVA = "10";
                console.log("cerco la fattura");
                var com = $location.search().COM_ID;


                this.stampaFat = function() {
                    $http.post('/contabilita/include/insert_fattura.php', this.reg)
                        .success(function(data) {
                            M.toast({
                                html: 'Intervento inserito...' + data,
                                inDuration: 1500
                            });
                        })
                        .error(function(status) {
                            alert("Errore di connessione!" + status)
                        });

                };
            }

            link: function(scope, element, attr, ctrl) {
                element.autocomplete({
                        source: '/contabilita/include/autocomplete.asp',
                        minChars: 3,
                        autoFill: true,
                        mustMatch: false,
                        cacheLength: 1,
                        select: function(event, ui) {
                            event.preventDefault();
                            scope.$applyAsync(function() {
                                // Update your model here
                                // use ctrl.reg to access this.reg in the controller
                            });
                        },


                    }
                };
            })

Youеще нужно добавить шаблон в директиву.Я не добавил его, потому что мне не понятен HTML-код вашего приложения.Вы также можете получить доступ к экземпляру контроллера в шаблоне, поэтому нет необходимости использовать $ scope внутри контроллера

0 голосов
/ 17 декабря 2018

Для интеграции внешней библиотеки с AngularJS ng-model используйте пользовательскую директиву:

app.directive("xngAutocomplete", function() {
     return {
         require: "ngModel",
         link: postLink,
     };
     function postLink(scope,elem,attrs,ngModel) {
         ̶$̶(̶d̶o̶c̶u̶m̶e̶n̶t̶)̶.̶r̶e̶a̶d̶y̶(̶f̶u̶n̶c̶t̶i̶o̶n̶(̶)̶{̶ ̶$̶(̶"̶#̶t̶a̶g̶s̶"̶)̶.̶a̶u̶t̶o̶c̶o̶m̶p̶l̶e̶t̶e̶(̶{̶
         elem.autocomplete({
             source: '/contabilita/include/autocomplete.asp',
             minChars: 3,
             autoFill: true,
             mustMatch:false,
             cacheLength: 1,
             select: function(event, ui) {
                event.preventDefault();
                ̶$̶(̶"̶#̶t̶a̶g̶s̶"̶)̶.̶v̶a̶l̶(̶u̶i̶.̶i̶t̶e̶m̶.̶l̶a̶b̶e̶l̶)̶;̶
                ngModel.$setViewValue(ui.item.label);
            }
         });
     }
})

Использование:

<input xng-autocomplete ng-model="reg.INTESTAZIONE" id="tags" type="text">

Директива внедряет код в элементы, которые имеют xng-autocomplete атрибут.Директива предоставляет элемент jQuery к коду в качестве второго параметра функции postLink.

Для получения дополнительной информации см.

0 голосов
/ 17 декабря 2018

AngularJS имеет «цикл дайджеста», который примерно аналогичен циклу событий браузера.Каждый цикл Angular решает, какие части DOM необходимо обновить.Ваш код jQuery никоим образом не ссылается на Angular, поэтому он не может знать, что ваши данные автозаполнения изменились или что экран должен обновляться.

Общий способ решить эту проблему - написать код jQuery. внутри Угловая функция, такая как компонент или директива.Есть много учебников о том, как это сделать.Именно поэтому возникает вопрос $scope.$apply(), это еще один способ сообщить Angular о необходимости обновления.

Я предлагаю вам создать директиву .В этой директиве у вас будет ссылка на версию текущего элемента в jQuery-версии, и вы можете вызвать функцию автозаполнения для этого.Затем используйте директиву в элементе #tags.

Я извлек это из старого проекта.Это немного устарело, но это должно показать идею.Ссылка на эти угловые документы для реальной сделки.

myApp.directive('autocomplete', function () {
    return function link(scope, element, attributes) {
        element.autocomplete({/* options here */});
    };
});

Затем в вашем html:

<div id="tags" autocomplete></div>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...