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