[英]Angular directive doesn't fire change event in ngModel
我為輸入元素創建了一個指令,該指令創建了一個自定義的select2下拉列表。
選擇元素后,原始輸入字段(用於通過ngModel過濾數據)將使用下拉菜單中的選定數據填充,但不會觸發輸入的change事件。
如果我手動更改輸入值,則表明過濾器正在工作。
這是我指令的代碼。
.directive('ajaxSelect2', ['$timeout', function($timeout) {
return {
restrict: 'A',
link: function (scope, element, attrs) {
switch(element.prop("tagName")) {
case 'INPUT':
$timeout(function() {
element.select2({
[ ... ] //the select2 part
});
});
break;
}
/* update the input value */
element.bind("change", function(e) {
scope.$apply(function() {
scope[attrs.ngModel] = e.val;
});
});
scope.$watch(element, function () {
console.log('x'); //not called
});
}
}
}])
我認為scope.apply()
的element.bind("change")
會觸發視圖更新,但是它不起作用。 有人知道如何告訴ngModel它有新數據嗎?
編輯:我想通了,問題是ngModel。 因為我必須過濾幾個值,所以我的模型是filter.foobar
。 這是行不通的。 如果將模型更改為foobar
,它將起作用。 我創建了一個小提琴來說明: http : //jsfiddle.net/StinsonMaster/6t3Nt/3/
我已經實現了一個自定義的select2下拉指令。 並將更改事件處理程序注冊到該指令鏈接到的元素。 當我從下拉列表中選擇一項時,將觸發輸入元素的change事件。 一切正常。 您可以嘗試我的實現:
指示
.directive('ajaxSelect2',['$timeout', function($timeout){
return {
restrict: 'A',
link: function(scope, element, attrs){
element.select2({
width: '200px',
createSearchChoice:function(term, data) { if ($(data).filter(function() { return this.text.localeCompare(term)===0; }).length===0) {return {id:term, text:term};} },
multiple: true,
data: [{id: 0, text: 'story'},{id: 1, text: 'bug'},{id: "ccc", text: 'task'}]
});
element.bind("change",function(e){
scope.$apply(function(){
scope[attrs.ngModel] = e.val.toString();
});
});
}
};
}]);
HTML
<body ng-app="selectApp">
<div ng-controller="selectCtrl">
<span>Selcted value: {{input}}</span>
<div>
<input id="test2" ng-model="input" ajax-select2/>
</div>
</div>
</body>
這是JSBin演示
[EDIT]對於財產訪問問題
自定義select2元素的ng-model是“ filter.foo”。 您想通知角度世界ng-model的值已由select2下拉過濾器更新。 但是您不能像這樣訪問二級屬性:
scope[attrs.ngModel] = e.val; // equal to scope['filter.foo'] which is the first level property 'filter.foo'
您應該通過以下方式訪問屬性:
var props = attrs.ngModel.split(".");
if(props.length>1){
scope[props[0]][props[1]] = e.val; //[] equals to dot '.'
}else{
scope[attrs.ngModel] = e.val;
}
這是一個jsFiddle演示
希望這會有所幫助。
由於element
不是scope
一部分,請嘗試使用返回它的函數 :
scope.$watch(function () {
return element;
}, function () {
console.log('x');
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.