假设我有两个相同控制器的实例" ControllerA"在包装控制器内使用ng-controller
as
语法进行实例化:
<div ng-contrller="MainController">
<div ng-controller="ControllerA as Ctrl1"></div>
<div ng-controller="ControllerA as Ctrl2"></div>
</div>
现在我想要实现的是我可以在Ctrl1.controllerFunction()
内调用类似MainController
的内容。通常我会使用$broadcast
和$on
来实现类似的行为,当没有相同控制器的两个实例时,所以我不能在这里使用它。我也不想在preventDefault
的事件对象上使用$broadcast
,因为它会变得太乱。
答案 0 :(得分:1)
没有一种简单的方法可以满足您的要求。 Ctrl1
的范围未定义MainController
,它位于子范围内。 Ctrl1
和Ctrl2
甚至不在彼此相同的范围内,因此没有必要使用不同名称的真正原因。您也可以ng-repeat
或ng-if
创建和销毁ControllerA
个实例,因此生命周期可能比MainController
更短。
处理此问题的更好方法是反转责任并使ControllerA
实例在创建时注册MainController
,并在销毁时取消注册。如果对MainController
也使用controllerAs语法,那么子控制器很容易在MainController上调用方法。
<div ng-controller="MainController as Main">
<div ng-controller="ControllerA as Ctrl1" ng-init="Ctrl1.init('Ctrl1')"></div>
<div ng-controller="ControllerA as Ctrl2" ng-init="Ctrl2.init('Ctrl2')"></div>
</div>
function ControllerA($scope) {
const vm = this;
vm.init = function(name) {
$scope.Main.register(name, vm);
$scope.$on('$destroy', function() {
$scope.Main.deregister(name);
});
}
}
然后在register
中编写合适的deregister
和MainController
函数以跟踪子控制器。类似的东西:
function MainController() {
const vm = this;
const children = {};
vm.register = function(name, vm) { children[name] = vm; }
vm.deregister = function(name) { delete children[name]; }
// ... and now you can do
if (children.Ctrl1) children.Ctrl1.controllerFunction();
}
您可以将init方法放在MainController
中,但这样会因为您需要子范围而难以取消注册。