簡體   English   中英

Angular指令不會觸發ngModel中的更改事件

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM