AngularJS:范围变量不够快速更新

时间:2014-09-24 03:34:33

标签: angularjs angularjs-directive angularjs-scope

我的指令中有以下代码。

//Directive Code
var BooleanWidgetController = function ($scope, $filter) {

    $scope.booleanOptions = [
        {
            displayText: '-- ' + $filter('i18n')('Widgets.Generics.Select') + ' --'
        },
        {
            value: 1,
            displayText: $filter('i18n')('Widgets.Generics.Yes')
        },
        {
            value: 0,
            displayText: $filter('i18n')('Widgets.Generics.No')
        }
    ];

    //Added inside watch because query was not being updated if filterUpdated was called using ng-change
    $scope.$watch('query', $scope.filterUpdated);
};

app.directive('acxBooleanColumnHeaderFilter', function () {
    return {
        restrict: 'A',
        replace: true,
        controller: ['$scope', '$filter', BooleanWidgetController],
        scope: {
            query: '=',
            filterUpdated: '&submit',
            columnHeading: '@'
        },
        templateUrl: 'mailSearch/directives/columnHeaderWidgets/boolean/booleanColumnHeaderWidget.tpl.html'
    };
});

//Template
<div class="columnHeaderWidget">
<div class="title pull-left">{{columnHeading}}</div>
<div style="clear:both"></div>
<select ng-model="query" ng-options="option.value as option.displayText for option in booleanOptions">
</select>

目前的方式运作良好。但是当我尝试做这样的事情时。

<select ng-model="query" ng-change="filterUpdated" ng-options="option.value as option.displayText for option in booleanOptions">

$ scope.query的更新速度不够快。因此,在调用$ scope.filterUpdated之后,$ scope.query正在更新。我在这里缺少什么?

1 个答案:

答案 0 :(得分:0)

这比看起来要复杂得多,如果你想了解真正的问题,请看一下:&#34; Explaining the order of the ngModel pipeline, parsers, formatters, viewChangeListeners, and $watchers&#34;。

总而言之,问题是:当ng-change函数被触发时,指令的绑定范围属性(在您的情况下为query)已在指令范围内更新,但不是在他们继承的范围内。

我建议的解决方法是:

  • 更改您的filterUpdated功能,使其从参数中获取query,而不是从scope获取,因为scope没有&# 39;尚未更新。

  • 在指令的scope中创建一个中间函数,以捕获ng-change事件和更新的范围属性。

  • 使用该中间函数调用filterUpdated函数并将query作为参数传递。

这样的事情:

var BooleanWidgetController = function ($scope, $filter) {

    $scope.booleanOptions = [
        {
            displayText: '-- ' + $filter('i18n')('Widgets.Generics.Select') + ' --'
        },
        {
            value: 1,
            displayText: $filter('i18n')('Widgets.Generics.Yes')
        },
        {
            value: 0,
            displayText: $filter('i18n')('Widgets.Generics.No')
        }
    ];

    $scope._filterUpdated = function(){ $scope.filterUpdated({query:$scope.query}); };        

    /** Remove this, you won't need it anymore
     ** $scope.$watch('query', $scope.filterUpdated);
     **/
};

更改您的HTML,使其如下所示:

<select ng-model="query" ng-change="_filterUpdated" ng-options="option.value as option.displayText for option in booleanOptions">

请记住更改filterUpdated以将查询用作参数,如下所示:

function filterUpdated(query){
   ...
}