AngularJS在Controller中刷新数据的正确方法

时间:2016-04-17 16:59:11

标签: angularjs

我有一个测试“hello”视图,显示“Hello {{username}}!”或“你好匿名!”。 该视图有自己的控制器,可通过url访问(由ui.router配置)。

然后我有一个方法setUsername(newUsername)getUsername()的UserModel。

还有一个带有控制器的日志视图,该控制器在登录成功时使用setUsername()方法,然后导航到“hello”视图。

代码如下所示:

HelloController中:

anguler.module('hello', ...
.config(function($stateProvider){
    $stateProvider
        .state('hello', {
            url: '/hello',
            views: {
                'main@': {
                    controller: 'HelloController as helloController',
                    templateUrl: 'app/hello/hello-tmpl.html'
                }
            },
        });
})
.controller('HelloController', function (UserModel) {
    var helloController = this;
    helloController.username = UserModel.getUsername();
})

顶部栏中还有一个“退出”按钮。因此,为了在“hello”视图中显示更改,我添加了UserModel在用户状态更改时调用的函数列表:

.service('UserModel', function() {
    var model = this;

    var username = '';
    var onChangesFunctions = [];

    function onChange() {
        onChangesFunctions.forEach(function(f) {
            f();
        });
    }

    model.onChange = function(f) {
        onChangesFunctions.push(f);
    };

    model.setUsername = function(newUsername) {
        username = newUsername;
        onChange();
    };

    model.clearUserData = function() {
        username = '';
        onChange();
    };

并在HelloController中添加了一个代码,以便向UserModel.onChangesFunctions添加一个监听器。

这种方法的问题是HelloController被多次初始化(每次用户导航到它时)以及每次将新函数注册为监听器时。

有没有更好的方法来刷新用户数据?

1 个答案:

答案 0 :(得分:1)

您的方法的问题是内存泄漏。正如您所说,当您的控制器被销毁并且新的控制器被创建时,您的功能仍将保留在服务中,并且由于该功能,应该被杀死的控制器仍然很可能在内存中。

我不清楚你的目标是什么;但是你可以做的就是在控制器被销毁时破坏这些功能:

.controller('HelloController', function (UserModel, $scope) {
    var helloController = this;
    helloController.username = UserModel.getUsername();

    $scope.$on('$destroy', function() {
      // either destroy all functions you add to the service queue
      // or
      // simply call the controller specific logic here, this will be called when your controller is destroyed
    });
});

另一种方法是听取$ stateChangeStart' /' $ stateChangeSuccess'事件

无论您选择何种方式,我强烈建议您避免将服务绑定到控制器实例特定逻辑。这是一种地狱的方式