ng-change后AngularJS范围更新

时间:2013-10-09 10:12:58

标签: angularjs

我有一个指令,集中我的选择HTML和功能,但我有一个问题,ng-model在ng-change发生后更新。

这是一个专注的jsfiddle示例:

http://jsfiddle.net/U3pVM/1568/

(代码,因为SO抱怨否则)

HTML:

<div ng-app="myApp">    
    <div ng-controller="MainCtrl">
        <p>fooId is currently : {{fooId}}</p>

        <app-drop-down model="fooId" options="fooOptions" opt-value="id" opt-label="label" on-change="dropDownChanged"></app-drop-down>
    </div>
</div>

JS:

var app = angular.module('myApp', []);

app.controller('MainCtrl', function ($scope, $log) {
    $scope.fooId = -1;

    $scope.fooOptions = [{
        id: 1,
        label: "A"
    }, {
        id: 2,
        label: "B"
    }];

    $scope.dropDownChanged = function (id) {
        $log.info('changed : ' + $scope.fooId + ' but really: ' + id);
    };
});

app.directive('appDropDown', function () {
    return {
        restrict: 'E',
        replace: true,
        scope: {
            model: '=',
            options: '=',
            onChange: '='
        },
        template:
            '<div><select ng-model="model" ng-options="a[optValue] as a[optLabel] for a in options" ng-change="changed()"></select></div>',
        link: function (scope, element, attrs) {
            scope.optValue = attrs.optValue;
            scope.optLabel = attrs.optLabel;

            scope.changed = function () {
                scope.onChange(scope.model);
            };
        }
    };
});

控制台记录:

更改:-1但确实:1

已更改:1但确实:2

将选择更改为A,然后更改为B.

正在更新但触发了ng-change后。

显然,我可以通过传递id(就像我这样)或在控制器中使用$ watch来解决这个问题,但这对某些更复杂的场景来说并不理想。

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

我知道这有点事后,但我遇到了类似的问题并且四处搜索我也发现了这个问题。由于似乎没有真正的答案,我想发布我最终做的事情,因为它可能在将来帮助其他人。这似乎适用于我的情况(以及你的小提琴),但由于我只是开始使用AngularJS,我可能会对“规则”做一些事情,所以任何专家都可以随意纠正我......

无论如何,这里是你的小提琴的更新版本我的更改:

http://jsfiddle.net/5vb5oL7e/1/

以下是该指令的实际代码:

app.directive('appDropDown', function () {
  return {
    restrict: 'E',
    replace: true,
    scope: {
        model: '=',
        options: '=',
        onChange: '='
    },
    template:
        '<div><select ng-model="model" ng-options="a[optValue] as a[optLabel] for a in options"></select></div>',
    link: function (scope, element, attrs) {
        scope.optValue = attrs.optValue;
        scope.optLabel = attrs.optLabel;
        scope.$watch('model', function(newValue, oldValue)
        {
          // Execute function on change
          if (scope.onChange !== undefined &&
            newValue !== undefined && oldValue !== undefined)
          {
            scope.onChange();
          }
        });
    }
  };
});

基本上,我所做的是在模型的链接功能中添加一个手表。在这个手表内部,我在定义时触发onChange函数。添加了对旧值和新值的未定义检查,以防止在页面加载时更改不需要的函数。

希望这有助于某人...

亲切的问候, 海诺