简体   繁体   English

AngularJS工厂采用双向数据绑定

[英]AngularJS factory two way data binding

I have an angular controller with some binded variables, and a factory that produces an array (used to populate options in a select control): 我有一个带有一些绑定变量的角度控制器,以及一个生成数组的工厂(用于在select控件中填充选项):

// Controller MyController
angular.module('users').controller('MyController', ['$scope', 'Authentication', 'MyFactory', 
    function($scope, Authentication, MyFactory) {
        $scope.user = Authentication.user;
        $scope.options = MyFactory.getOptions($scope.user.firstName, $scope.user.lastName);
        ...
    }
    ...
}

// Factory MyFactory
angular.module('users').factory('MyFactory', 
    function() {
        var _this = this;
        _this._data = {
            getOptions: function(firstName, lastName){
                return [
                    firstName + ' ' + lastName,
                    lastName  + ' ' + firstName
                    ...
                ];  
            }
        };
        return _this._data;
    }
);

It works well for the first time, but does not keep data in sync between the controller and the factory. 它第一次运行良好,但不保持控制器和工厂之间的数据同步。

The intended effect is that a change in an argument of MyFactory.getOptions() modifies the resulting array assigned to $scope.options . 预期的效果是MyFactory.getOptions()参数的更改会修改分配给$scope.options的结果数组。

It works the first time because you are calling a function which returns a new array, and then your view only ever references that array, and never calls the function again. 它是第一次工作,因为你正在调用一个返回一个新数组的函数,然后你的视图只引用该数组,并且从不再次调用该函数。 The easiest solution is to add a $scope.$watch for your $scope.user variable that recalls the MyFactory.getOptions function. 最简单的解决方案是为$scope.user变量添加$scope.$watch ,以调用MyFactory.getOptions函数。

// Controller MyController
angular.module('users').controller('MyController', ['$scope', 'Authentication', 'MyFactory', 
    function($scope, Authentication, MyFactory) {
        $scope.user = Authentication.user;
        $scope.options = MyFactory.getOptions($scope.user.firstName, $scope.user.lastName);
        $scope.$watch("user", function(newVal,oldVal,scope) {
            scope.options = MyFactory.getOptions(newVal.firstName, newVal.lastName);
        });
        ...
    }
    ...
}

Something like that anyway. 无论如何都是这样的。 Might have to play around with the syntax a bit. 可能需要稍微使用语法。


Per your comments, try something like this: 根据您的意见,尝试这样的事情:

// Controller MyController
angular.module('users').controller('MyController', ['$scope', 'Authentication', 'MyFactory', 
    function($scope, Authentication, MyFactory) {
        $scope.user = Authentication.user;
        $scope.options = MyFactory.getOptions($scope, "user");
        ...
    }
    ...
}

// Factory MyFactory
angular.module('users').factory('MyFactory', 
    function() {
        var _this = this;
        _this._data = {
            getOptions: function(scope, property){
                var updateableArray = [];
                function updateArray(user) {
                    //delete all elements of updateableArray
                    updateableArray.clear();
                    //add all the new elements of updateableArray from user argument
                    updateableArray.push(firstName + ' ' + lastName);
                    updateableArray.push(lastName  + ' ' + firstName);
                    ....
                }
                scope.$watch(property, function(newVal,oldVal,watchScope) {
                    updateArray(newVal);
                });
                updateArray(scope[property]);
                return updateableArray;  
            }
        };
        return _this._data;
    }
);

There is certainly a better way to organize it, but hopefully it's enough to help you get the idea. 当然有更好的方法来组织它,但希望它足以帮助你理解它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM