1

我有三个 Angular 1.5 组件:ReportFilterClientSelect, ZoneSelect.

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>

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

我的问题:

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

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

4

2 回答 2

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...
于 2016-08-04T22:07:37.527 回答
1

我相信首选的方法是在您的子指令中添加一个名为 api 的范围属性:

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>

你现在可以从父控制器调用函数

$scope.foo.someFN()
于 2016-08-04T22:03:50.203 回答