观察服务中的值以及角度检测变化的机制

时间:2016-04-14 21:21:49

标签: angularjs

我有一些指令,它们会在视图中显示相同的数据模型。在ajax调用之后将生成数据。目前我将ajax调用放入服务中,一旦ajax调用返回,服务中的某些变量将被更新。像这样:

//service
serviceModule.service("myService",function(){
     this.data = [];
     this.ajaxCall = function(){
          ...
         //in ajax success call back
          this.data = response.data;
     }; 
});

//directive A
moduleA.directive("directiveA",function(myService){
     return{
         templateUrl:'someUrl.html'
         link: function(scope){
            scope.data = myService.data;
         } 
     }

})

// someUrl.html
<div ng-repeat="line in data">
{{line.abc}}
</div>

我的第一个问题是我不确定这是否是基于ajax返回更新视图的好方法(我的意思是将返回的数据作为服务中的属性,因为从设计的角度来看,它只是要在某处分配的返回值,而不是某些属性......)

我尝试了几种方法来自动检测服务属性的变化,这导致了一些问题:

1)我的原始方法(如上面的伪)不起作用,我想知道为什么。我想通过使用“scope.data = myService.data”,myService.data和scope.data实际上指向相同的内存地址,一旦内存地址的内容发生变化,“scope.data”也会发生变化,然后应该被指令检测到。如果有人可以从记忆的角度介绍我的机制,将会非常有帮助。

2)然后我做了一些谷歌搜索,发现这个有用的帖子: AngularJS : How to watch service variables? 然后我稍微改变了指令:

//directive A
moduleA.directive("directiveA",function(myService){
     return{
         templateUrl:'someUrl.html'
         link: function(scope){
            scope.service = myService;
         } 
     }

})

在html中,我只使用service.data而不是数据。在我在服务中添加 $ rootScope。$ apply()之前它无效:

serviceModule.service("myService",function(){
         this.data = [];
         this.ajaxCall = function(){
             //in ajax success call back
              this.data = response.data;
              **$rootScope.$apply();**
         }; 
    });

那么,任何人都可以解释这个$是如何应用的,$ watch适用于角度?

非常感谢!

1 个答案:

答案 0 :(得分:0)

Angular臭名昭着的$ digest周期是魔术背后的伎俩。会发生的是,在每个$ digest周期中,angular会在每个$ scope(从$ rootScope一直到最后一个隔离范围)上运行应用程序中设置的所有$ watchers(如绑定变量),并查看是否有更改。如果有,则更新视图。如果下面有一个更改,我们有双向绑定 - 它会重新开始,直到它没有任何改变。 话虽如此,您现在可以在构建角度应用时理解您的主要目标 - 减少$摘要和减少$ watch。减少$摘要,这样我们就不需要多次运行所有的手表了,并且#34;窒息了#34;线程。减去$ watch - 所以每个$ digest都是尽可能的。 现在......使用$ scope。$ apply肯定会起作用,因为它开始$ digest周期。问题 - 它从顶部开始$摘要周期。这一切都取决于您的需求。 所以你应该理解这种需要 - 例如,如果你的指令在同一个父指令下,那么就足够了:$ scope。$ digest(),它只会刷新&#34;父母及其子女,不涉及应用程序的其余部分。 如果您的指令被传播,那么您可能希望使用来自ajax调用的一些promise而不是使用绑定来更新它们,然后在指令本身中执行本地$ scope。$ digest()。 所以你的服务可能如下:

serviceModule.service("myService",function($q){
var deferred = $q.defer();
         this.data = [];
         this.ajaxCall = function(){
             //in ajax success call back
              this.data = response.data;
deferred.notify(this.data);
         }; 
this.promise = deferred.promise;
    });

在你的指令中,你可以这样做而不是绑定:

moduleA.directive("directiveA",function(myService){
     return{
         templateUrl:'someUrl.html',
         link: function(scope){
            var promise = myService.promise;
promise.then(null, null, function(data){
scope.myData = data;
});
         } 
     }

})

$q服务&#34;聪明地&#34;在resolverejectnotify时启动摘要。 你可以在这里阅读一篇很棒的帖子:http://www.bennadel.com/blog/2778-exploring-q-and-scope-digest-integration-in-angularjs.htm

这是我解释$摘要和2种可能解决方案的最短路径。可以使用更多方法。这是另一篇展示2种方法的帖子:http://webiks.com/communication-in-an-angular-app-two-approaches/

希望这有帮助