如何从其父级访问嵌套组件的控制器?
How can I access the controller of a nested component from its parent?
我有三个 Angular 1.5 组件:ReportFilter
和 ClientSelect
、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
是双向数据绑定,因此当用户选择客户端或区域时,相应的属性会在我的 ReportFilter
的选择中更新.
我的问题:
如何从 ReportFilter
的控制器内部调用 ClientSelect
或 ZoneSelect
组件的控制器上的 reset()
方法?
React 有一个 ref
标签,可让您访问控制器以调用其上的方法。
我认为首选方法是在您的子指令中添加一个名为 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()
没有 built-in 方式(不像 React,正如你提到的 :)
一个可能的解决方案是让 children 要求他们的 parent,并向其注册:
// 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,
...
};
})
如果您不想要children和parent组件之间的耦合,那么您可以重新设计children以便他们所有的数据,我的意思是所有,整个事情,都来自他们的 parent。在这种情况下,要重置 clientSelect
,parent 控制器只需要清除与其共享的数据,即执行:
// in the parent controller
this.selections.client = {}; // or null or...
我有三个 Angular 1.5 组件:ReportFilter
和 ClientSelect
、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
是双向数据绑定,因此当用户选择客户端或区域时,相应的属性会在我的 ReportFilter
的选择中更新.
我的问题:
如何从 ReportFilter
的控制器内部调用 ClientSelect
或 ZoneSelect
组件的控制器上的 reset()
方法?
React 有一个 ref
标签,可让您访问控制器以调用其上的方法。
我认为首选方法是在您的子指令中添加一个名为 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()
没有 built-in 方式(不像 React,正如你提到的 :)
一个可能的解决方案是让 children 要求他们的 parent,并向其注册:
// 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,
...
};
})
如果您不想要children和parent组件之间的耦合,那么您可以重新设计children以便他们所有的数据,我的意思是所有,整个事情,都来自他们的 parent。在这种情况下,要重置 clientSelect
,parent 控制器只需要清除与其共享的数据,即执行:
// in the parent controller
this.selections.client = {}; // or null or...