如何从其父级访问嵌套组件的控制器?

时间:2016-08-04 21:45:37

标签: angularjs angularjs-components

我有三个Angular 1.5组件:ReportFilterClientSelectZoneSelect

ReportFilter里面有两个组件

<!-- Report Filter -->
<div>
    <client-select client="$ctrl.selections.client"></client-select>
    <zone-select zone="$ctrl.selections.zone"></zone-select>
    <button ng-click="$ctrl.search()">Get Report</button>
    <button ng-click="$ctrl.clear()">Clear</button>
</div>

clientzone是双向数据绑定,因此当用户选择客户端或区域时,相应的属性会在我的ReportFilter中更新选择。

我的问题:

如何从reset()控制器内部的ClientSelectZoneSelect组件的控制器上调用ReportFilter方法?

React有一个ref标记,可让您访问控制器以调用其上的方法。

2 个答案:

答案 0 :(得分:2)

没有内置方式(与React不同,正如您所说:)

一个可能的解决方案是让孩子们要求他们的父母,并注册自己:

    // child directive
    .directive('clientSelect', function() { // `.component` is similar...
        return {
            ...
            controller: ClientSelect,
            require: ['clientSelect', 'reportFilter'],
            link: function(scope, elem, attrs, ctrls) {
                ctrls[1].setClientSelect(ctrls[0]);
                // do not forget to deregister, just in case
                scope.$on('$destroy', function() {
                    ctrls[1].setClientSelect(null);
                });
            }
        };
    })

    // parent directive
    .directive('reportFilter', function() {
        function ReportFilter() {
            ...
        }

        ReportFilter.prototype.setClientSelect = function(clientSelect) {
            this.clientSelect = clientSelect;
        };

        ReportFilter.prototype.somethingElse = function() {
            // reset the clientSelect:
            this.clientSelect.reset();
        };

        return {
            ...
            controller: ReportFilter,
            ...
        };
    })

如果你想要孩子和父组件之间的耦合,那么你可以重新设计孩子,以便他们所有的数据,我的意思是所有,整个事情,来自他们的父母。在这种情况下,要重置clientSelect,父控制器只需要清除它与之共享的数据,即执行:

// in the parent controller
this.selections.client = {}; // or null or...

答案 1 :(得分:1)

我认为首选的方法是在你的child指令中添加一个名为api的范围属性:

$('body').on('focus', '#social_stream_content textarea', function (event) {
  // Focus handler
}).on('focusout', '#social_stream_content textarea', function(event) {
  // Focusout handler
});

然后当你调用指令时,你只需传递一个范围属性:

app.directive('childDirective', function() {
  return {
    scope: {
      api: "=?"
    },
    link: function(scope, elem, attrs) {
      return {
        scope.someFN = function() {
           // do stuff.
        };

        scope.api = {
         someFN: scope.someFN
        };
      };
    };
  };
});

现在您可以使用

从父控制器调用函数
<div ng-controller="parentCtrl">
  <child-directive api="foo"></child-directive>
</div>