控制器之间的角度共享数据:服务与事件

时间:2014-03-23 23:00:49

标签: javascript angularjs

在控制器之间共享数据是否有一般的经验法则?

我已经看到了两种如何实现这一目标的答案:

  1. 将服务注入包含共享数据的两个控制器
  2. 使用$ scope。$ broadcast('someEvent',sharedArg)和$ scope。$ on('someEvent',sharedArg)
  3. 我不确定何时最好使用一种方法而不是另一种方法。

    此外,关于方法#1,我真的不喜欢一件事。这是一个玩具示例,取自一些真实的代码:

    angular.module('profileService', [])
           .factory('profileService', 
      [  
        function() {
          var selectedProfile = { profileId: null };
    
          return {
            getProfile: function(profileId, callback) {
              // marshall ajax request into format server will know how to handle
              // ajax call to server
              // marshall ajax response into format UI (controller) will know how to handle
            },
    
            createProfile: function(callback) { ... // ajax call to server ... },
            updateProfile: function(callback) { ... // ajax call to server ... },
            deleteProfile: function(callback) { ... // ajax call to server ... },
    
            getSelectedProfile: function() {
              return selectedProfile.profileId;
            },
    
            setSelectedProfile: function(profileId) {
              selectedProfile.profileId = profileId;
            },
          };
        }
      ]);
    

    这似乎是糟糕的设计。该服务(与我们的大部分服务一样)用于转换和向服务器发出请求。我们的大部分服务都是无国籍的。为测试等注入模拟服务是微不足道的......

    但现在突然间我们的服务状态。这似乎是一个坏主意。

    另一种方法可能是构建一个仅用于在控制器之间共享数据的服务(并且永远不会进行后端调用),但这并不是所有的开胃菜。它闻起来像一个提供全局命名空间的服务,看起来不是很好的设计。

    只是想知道,有没有关于方法#1 vs#2的想法。在服务中包含国家不一定是坏事吗?事件是分享状态的更好方法吗?

    感谢。

2 个答案:

答案 0 :(得分:2)

official AngularJS guide for controllers建议使用服务进行共享状态:

  

请勿使用控制器:

     
      
  • 跨控制器共享代码或状态 - 改为使用角度服务。
  •   

答案 1 :(得分:1)

使用服务来共享数据/状态很好(webcam.isStreaming,socket.isConnected等),但是像“selection”这样的东西不属于profileService,例如它应该可以有多个选择。

事件不是用于共享状态,而是用于......事件。比如“includeContentLoaded”,“webcamReady”,“socketMessage”等。 控制器可能没有准备好(通过ng-include加载异步)并错过事件。

方法3:您是否尝试过UI Router了吗?它是围绕各州组织的 您可以使用$ stateParams或resolve来传递所选的个人资料 其中一些也可以使用ngRoute,但非常有限。

方法4:您可以使用$scope在父控制器和子控制器之间共享数据。
好处/缺点是选择寿命与范围有关 这会产生一些耦合/复杂性,但不会超过profileSelectionsService 如果父控制器写入$ scope并且子控制器读取,则工作得很好。 当两个控制器都想写入$ scope

时,它会变得棘手