在 angularjs 中委托控制器之间的函数调用

delegating function calls between controllers in angularjs

以下情况:

有两个带有控制器的指令 (A & B) - 它们都是另一个控制器 (C) 的子级。

控制器 A 为其模型管理内容。 现在控制器 C 需要调用控制器 A 的函数来修改一些东西。此外,它需要访问某些属性并读取它们。

我不确定什么是正确的沟通方式。以及是否坚持一种方法。

下面是一个小代码示例,可以更具体地说明问题。

首先有一个提供者,组件可以在其中注册自己。

angular.module('components', [])
       .provider('db', function(){
         this.registerComponent = function(name, component){
           ...
         }
       });

现在有一个指令和一个显示具体组件的控制器 (A)。

angular.module('components')
       .directive('componentDashboard', function(){
       return {
         scope:{
           concreteComponents: '='
         },
         controller: function($scope){
           $scope.model = concreteComponents;
           $scope.model.someImportantProp = "foo";
           $scope.addComponent = function(c){...}
         }
       }
       }) 

基本上就是这样。指令 componentDashboard 可以显示一组注册到数据库提供程序的组件。

有像addComponent 这样的控制器函数(A) 需要从控制器外部调用(控制器B 想调用它)。此外,控制器 B 想要访问不同的属性等等。

执行此操作的首选方法是什么?

目前使用的范式有:

1) 工厂破解?!基本上有一个具有一些功能的工厂:

angular.module('components')
        .factory('componentStub', function($log){
          return {
            addComponent : function(c){
              $log.error("stub not overwritten");
            }
          }
        })

这些函数现在被组件的指令覆盖:

angular.module('components')
   .directive('componentDashboard', function(componentStub){
   return {
     scope:{
       concreteComponents: '='
     },
     controller: function($scope){
       $scope.model = concreteComponents;
       $scope.model.someImportantProp = "foo";
       $scope.addComponent = function(c){...}
       componentStub.addComponent = function(c){
         $scope.addComponent(c);
       }
     }
   }
   })

2) 基于事件

angular.module('components')
       .factory('notificationCenter', function(){
         return {
           registerToNotification: function(id, not, cb){..}
         } 
       })
       .directive('componentDashboard', function(notificationCenter){
         return {
           scope:{
             concreteComponents: '='
           },
         controller: function($scope){
           $scope.model = concreteComponents;
           $scope.model.someImportantProp = "foo";
           $scope.addComponent = function(c){...}
           notificationCenter.registerToNotification("foo",     "doAddComponent", function(c){
              $scope.addComponent(c)
            }
         }
       }
       }) 

目前两种方法都在使用。使用它有一些优点。它发展迅速,对它的依赖或限制很少。并且有效。

但是!我不确定这是否是一个好方法。我在这方面遇到了一些糟糕的维护,它变得越复杂(可以说一些组件可以添加而一些不能 -> 状态)就越感觉不是正确的方法。

应该如何解决这个问题?

抱歉问题太长了,谢谢指教

Schemii

有多种方法可以解决这个问题。确保它的可维护性归结为隔离:让不同的组件独立工作,而不相互依赖。

结合以下任何策略(从最容易到更难实施):

  • 让 parent 视图将模型(或其部分)传递给 child 指令(通过属性)
  • $watch 主要针对更改 controller/directive 对更改做出反应。
  • 让 parent controller/directive 注册 ($scope.$on) 某些事件的回调。孩子们可以 $emit 事件向上到他们的 parents。 Parents 可以 $broadcast 事件向下到他们的 children.
  • 让child指令公开一个callback/expression(参见isolate scope options中的&前缀)
  • 共享一个将处理模型更改的(单例)服务实例。在需要的地方注入这个服务。由于这是一个单例,您必须确保在范围被销毁时清除回调,否则您将泄漏内存。

希望对您有所帮助。

干杯。