Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angularjs 在控制器生存期内检测并使用已更改的控制器依赖项_Angularjs_Dependency Injection_Route Provider - Fatal编程技术网

Angularjs 在控制器生存期内检测并使用已更改的控制器依赖项

Angularjs 在控制器生存期内检测并使用已更改的控制器依赖项,angularjs,dependency-injection,route-provider,Angularjs,Dependency Injection,Route Provider,为了便于理解,假设我有一个AngularJS应用程序,它具有与Stackoverflow相似的数据,以便: 正在使用常用的ngRoute/$routeProvider 有一个userService,返回登录用户的收藏夹和忽略标记列表-这两个列表都是同时获取的,请求它们是一个承诺,即在解析时缓存这些列表 具有显示问题列表的视图,其中包含提供其模型的QuestionsController(类似于Stackoverflow) QuestionsController请求问题,然后依靠缓存的标记列表对其进

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

  • 正在使用常用的ngRoute/$routeProvider
  • 有一个
    userService
    ,返回登录用户的收藏夹忽略标记列表-这两个列表都是同时获取的,请求它们是一个承诺,即在解析时缓存这些列表
  • 具有显示问题列表的视图,其中包含提供其模型的
    QuestionsController
    (类似于Stackoverflow)
  • QuestionsController
    请求问题,然后依靠缓存的标记列表对其进行适当标记
  • 当控制器依赖于其他异步数据时,我们应该将这些数据卸载到路由
    resolve
    部分,因此当控制器被实例化时,这些承诺已经得到解决。因此,我将标签列表的获取卸载到它,以便两个列表都准备好并注入控制器。这一切都按预期进行

    “我的问题列表”视图的附加功能是,当用户单击问题上显示的标记时,会自动将该标记添加到收藏夹列表中(或当该标记已经是收藏夹列表的一部分时,将其关闭)

    路由配置

    ...
    .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();
            });
    };
    
    问题 当视图显示时,将加载所有问题并根据提供的标记列表正确标记。现在,当一个用户点击一个特定的标签,该标签的最喜欢的状态得到更改时,我的控制器的依赖关系应该会自动更新

    既然我的控制器已经实例化,并且在实例化过程中注入了标记列表,我该怎么做呢

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

    只要您的“已解析”变量引用其他地方使用的相同对象,他们是同一个人

    因此,如果您的
    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
      }
    }
    

    ,举例说明

    我知道这一点,但我正试图按预期使用缓存,这意味着我将使现有缓存无效,并用获取的数据替换它。这也比遍历项目、更改项目、添加新项目和删除缺少的项目需要更少的处理。。。我可能会使用splice和join,因为我最终得到的是相同的数组,但内容不同……但仍然存在通知控制器在新标记准备好时标记问题的问题。也许我可以通过承诺而不是事件传播……我想你有一些克隆/缓存的数据。但是没有魔法。您可以迭代自己并更改内容,但不能更改引用。或者,您要求Angular“监视更改”,很遗憾,即使监视更改只适用于相同的数组引用。否则它也不会起作用。@RobertKoritnik,对,但我的意思是在概念上-因为您似乎对Angular的自动更新依赖项的功能有这样的期望