【问题标题】:AngularJS : Scope variable not updating fast enoughAngularJS:范围变量更新速度不够快
【发布时间】:2014-09-24 11:59:09
【问题描述】:

我的指令中有以下代码。

//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.query 在 $scope.filterUpdated 被调用之后被更新。我在这里错过了什么?

【问题讨论】:

    标签: angularjs angularjs-directive angularjs-scope


    【解决方案1】:

    这比看起来要复杂得多,如果你想了解真正的问题,看看这个:“Explaining the order of the ngModel pipeline, parsers, formatters, viewChangeListeners, and $watchers”。

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

    我建议的解决方法是:

    • 更改您的filterUpdated 函数,使其从参数中获取query,而不是从其scope 中获取它,因为它的scope 尚未更新。

    • 在指令的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){
       ...
    }
    

    【讨论】:

    • 我的代码已经按照问题中提到的那样工作,但我无法理解的是为什么查询范围变量更新速度不够快。如果我进行像 $scope.query = 0; 这样的级联调用$scope.filterUpdated();,filterUpdated 函数不会将 $scope.query 设为 0,而 $scope.query 将具有先前的值。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-24
    • 2013-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多