【问题标题】:delegating function calls between controllers in angularjs在angularjs中的控制器之间委托函数调用
【发布时间】:2016-01-08 19:52:47
【问题描述】:

以下情况:

有两个带有控制器的指令 (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 可以显示一组注册到 db 提供程序的组件。

有像 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)
            }
         }
       }
       }) 

目前两种方法都使用。使用它有一些优点。它发展迅速,几乎没有依赖或限制。它有效。

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

应该如何解决这个问题?

抱歉问了这么长的问题,谢谢建议

架构

【问题讨论】:

    标签: angularjs controller communication directive


    【解决方案1】:

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

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

    • 让父视图将模型(或模型的一部分)传递给子指令(通过属性)
    • $watch 用于更改主控制器/指令以对更改做出反应。
    • 让父控制器/指令注册 ($scope.$on) 回调某些事件。孩子们可以$emit事件向上他们的父母。家长可以$broadcast 事件向下传递给他们的孩子。
    • 让子指令公开一个回调/表达式(参见isolate scope options 中的& 前缀)
    • 共享将处理模型更改的(单例)服务实例。在需要的地方注入此服务。由于这是一个单例,因此您必须确保在作用域被销毁时清理回调,否则您会泄漏内存。

    希望这会有所帮助。

    干杯。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-01-02
      • 2015-01-29
      • 1970-01-01
      • 1970-01-01
      • 2018-09-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多