在控制器生命周期内检测并使用更改的控制器依赖性

时间:2015-02-18 16:14:05

标签: angularjs dependency-injection route-provider

为了便于理解,假设我有一个AngularJS应用程序,它具有与Stackoverflow类似的数据,以便:

  1. 正在使用通常的ngRoute / $ routeProvider
  2. userService返回收藏夹忽略登录用户的标记列表 - 两个列表同时被提取并且请求它们是承诺当解决时缓存这些列表
  3. 有一个视图,显示提供其模型的QuestionsController的问题列表(类似于Stackoverflow)
  4. QuestionsController提出问题请求,然后依赖于缓存的标记列表来正确标记
  5. 当控制器依赖其他异步数据的recommended guideline时,我们应该将这些数据卸载到路由resolve部分,这样当控制器被实例化时,这些promise已经被解析。因此,我将标记列表提取到其中,以便两个列表都准备就绪并注入控制器。这一切都按预期工作。

    我的问题列表视图的附加功能是,当用户点击问题上显示的标记时,会自动将此标记添加到收藏列表(或当该标签已经是最喜欢的列表的一部分。)

    路线配置

    ...
    .when({
        templateUrl: "...",
        controller: "QuestionsController as context",
        resolve: {
            tags: ["userService", function(userService) {
                return userService.getMyTags();
            }]
        }
    })
    .when(...)
    ...
    

    控制器伪代码

    QuestionsController.prototype.markQuestions = function() {
        this.model.questions.forEach(function(q, idx) {
            // "myTags" is resolve injected dependency
            q.isFavourite = q.tags.any(myTags.favourite);
            q.isIgnored = q.tags.any(myTags.ignored);
        });
    };
    QuestionsController.prototype.toggleTag = function(tag) {
        var self = this;
        // change tag subscription
        tagService
            .toggleFavourite(tag)
            .then(function() {
                // re-mark questions based on the new set of tags
                self.markQuestions();
            });
    };
    

    问题

    当显示视图时,所有问题都会被加载并按照提供的标记列表正确标记。现在,当用户点击特定标签并且该标签的收藏状态发生变化时,我的控制器的依赖关系应该自动更新。

    我该怎么做,因为我的控制器已经实例化并且在实例化期间注入了标记列表?

    我想避免在我的控制器中手动加载这些列表,因为在这种情况下我应该在实例化期间执行相同的操作并重用相同的功能而不是在两个地方(路由解析和控制器内部)。

1 个答案:

答案 0 :(得分:0)

只要你的“已解决”变量引用其他地方使用的相同对象,它们就是同一个。

因此,如果您的userService.getMyTags在概念上与以下内容相同:

.factory("userService", function($timeout){
  var tags = [/*...*/];
  return {
     getMyTags: function(){
        return $timeout(function(){ return tags; }, 500);
     },

     addTag: function(newTag){
        tags.push(newTag);
     }
  }
});

然后对任何地方的标签的任何引用都会得到更改:

.controller("ViewCtrl", function($scope, tags){
  $scope.tags = tags; // tags is "resolved" with userService.getMyTags()
})
.controller("AddTagCtrl", function($scope, userService){
  $scope.addTag = function(newTag){
     userService.addTag(newTag); // changes will be reflected in ViewCtrl
  }
}

plunker,以说明