2

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

这是一个集中的 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 值来解决这个问题,但这对于某些更复杂的场景并不理想。

有任何想法吗?

4

1 回答 1

1

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

无论如何,这是您的 Fiddle 的更新版本,其中包含我的更改:

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 函数。添加了对旧值和新值的未定义检查,以防止在页面加载时更改不需要的功能。

希望这可以帮助某人...

亲切的问候,海诺

于 2014-10-09T12:50:25.990 回答