我正在尝试使用自动完成的jQuery UI将值插入angularjs形式。问题是,当我使用$ http发送数据时,来自自动完成输入的值不会更新ng-model! 我读了一些有关$ 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');;
}
});
};
})
答案 0 :(得分:0)
AngularJS有一个“摘要循环”,大致类似于浏览器的事件循环。每个周期,Angular决定需要更新DOM的哪些部分。您的jQuery代码不会以任何方式引用Angular,因此无法知道您的自动填充数据已更改,或者屏幕需要更新。
解决此问题的一般方法是在中编写基于Angular的函数(如组件或指令)的jQuery代码。关于如何执行此操作的教程很多。这也是$scope.$apply()
出现的原因,这是告诉Angular需要进行更新的另一种方式。
我建议您创建一个directive。在该指令中,您将引用当前元素的jQuery封装版本,并且可以在其上调用自动完成功能。然后在#tags
元素中使用指令。
我从一个旧项目中提取了这个。这有点过时了,但是应该可以证明这个想法。请参考那些有角度的文档以获取真正的交易。
myApp.directive('autocomplete', function () {
return function link(scope, element, attributes) {
element.autocomplete({/* options here */});
};
});
然后,在您的html中:
<div id="tags" autocomplete></div>
答案 1 :(得分:0)
您应该将自动完成功能包装在指令中,因为我看到它对angular应用程序之外的ui进行了许多更改,并且我认为许多更改都会影响angular生成的html。
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
});
},
}
};
})
您仍然需要向指令添加模板。我没有添加它,因为我不清楚您的应用的HTML。 您也可以在模板中访问控制器实例,因此无需在控制器内部使用$ scope
答案 2 :(得分:0)
要将外部库与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
函数的第二个参数公开给代码。
有关更多信息,请参见