如果您打算掌握已经实例化的另一个组件的控制器,并且如果您遵循基于组件/指令的方法,则始终可以require
遵循某个层次结构的另一个组件中的控制器(一个组件的实例)。
例如:
//some container component that provides a wizard and transcludes the page components displayed in a wizard
myModule.component('wizardContainer', {
...,
controller : function WizardController() {
this.disableNext = function() {
//disable next step... some implementation to disable the next button hosted by the wizard
}
},
...
});
//some child component
myModule.component('onboardingStep', {
...,
controller : function OnboadingStepController(){
this.$onInit = function() {
//.... you can access this.container.disableNext() function
}
this.onChange = function(val) {
//..say some value has been changed and it is not valid i do not want wizard to enable next button so i call container's disable method i.e
if(notIsValid(val)){
this.container.disableNext();
}
}
},
...,
require : {
container: '^^wizardContainer' //Require a wizard component's controller which exist in its parent hierarchy.
},
...
});
现在,以上这些组件的用法可能是这样的:
<wizard-container ....>
<!--some stuff-->
...
<!-- some where there is this page that displays initial step via child component -->
<on-boarding-step ...>
<!--- some stuff-->
</on-boarding-step>
...
<!--some stuff-->
</wizard-container>
您可以通过多种方式设置require。
(无前缀)-在当前元素上找到所需的控制器。如果找不到,则引发错误。
?-尝试找到所需的控制器,或者如果未找到,则将null传递给链接fn。
^-通过搜索元素及其父元素找到所需的控制器。如果找不到,则引发错误。
^^-通过搜索元素的父级找到所需的控制器。如果找不到,则引发错误。
?^-尝试通过搜索元素及其父元素来定位所需的控制器,或者如果未找到,则将null传递给链接fn。
?^^-尝试通过搜索元素的父元素来定位所需的控制器,如果找不到链接,则将null传递给链接fn。
旧答案:
您需要注入$controller
服务以实例化另一个控制器中的一个控制器。但是请注意,这可能会导致一些设计问题。您始终可以创建遵循单一职责的可重用服务,并根据需要将其注入控制器中。
例:
app.controller('TestCtrl2', ['$scope', '$controller', function ($scope, $controller) {
var testCtrl1ViewModel = $scope.$new(); //You need to supply a scope while instantiating.
//Provide the scope, you can also do $scope.$new(true) in order to create an isolated scope.
//In this case it is the child scope of this scope.
$controller('TestCtrl1',{$scope : testCtrl1ViewModel });
testCtrl1ViewModel.myMethod(); //And call the method on the newScope.
}]);
无论如何,您都无法调用,TestCtrl1.myMethod()
因为您已将方法附加到$scope
而不是控制器实例上。
如果您共享控制器,那么这样做总会更好:
.controller('TestCtrl1', ['$log', function ($log) {
this.myMethod = function () {
$log.debug("TestCtrl1 - myMethod");
}
}]);
在消费时:
.controller('TestCtrl2', ['$scope', '$controller', function ($scope, $controller) {
var testCtrl1ViewModel = $controller('TestCtrl1');
testCtrl1ViewModel.myMethod();
}]);
在第一种情况下,实际上$scope
是您的视图模型,在第二种情况下,它是控制器实例本身。
TestCtrl1
使用服务。