使用AngularJS,我如何注入一个控制器在另一个控制器中使用?
我有以下片段:
var app = angular.module("testApp",['']); app.controller('TestCtrl1',['$scope',function ($scope) { $scope.myMethod = function () { console.log("TestCtrl1 - myMethod"); } }]); app.controller('TestCtrl2','TestCtrl1',function ($scope,TestCtrl1) { TestCtrl1.myMethod(); }]);
当我执行这个,我得到的错误:
Error: [$injector:unpr] Unknown provider: TestCtrl1Provider <- TestCtrl1 http://errors.angularjs.org/1.2.21/$injector/unpr?p0=TestCtrl1Provider%20%3C-%20TestCtrl1
我应该甚至试图使用另一个控制器里面的控制器,或者我应该使这个服务?
例如:
//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>
(no prefix) – Locate the required controller on the current element. Throw an error if not found.
? – Attempt to locate the required controller or pass null to the link fn if not found.
^ – Locate the required controller by searching the element and its parents. Throw an error if not found.
^^ – Locate the required controller by searching the element’s parents. Throw an error if not found.
?^ – Attempt to locate the required controller by searching the element and its parents or pass null to the link fn if not found.
?^^ – Attempt to locate the required controller by searching the element’s parents,or pass null to the link fn if not found.
老答案:
您需要注入$controller
服务以在另一个控制器中实例化控制器。但请注意,这可能会导致一些设计问题。您可以随时创建遵循单一职责的可重用服务,并根据需要将它们注入到控制器中。
例:
app.controller('TestCtrl2','$controller',$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"); } }]);
和消费do:
.controller('TestCtrl2',$controller) { var testCtrl1viewmodel = $controller('TestCtrl1'); testCtrl1viewmodel.myMethod(); }]);
在第一种情况下,真正的$ scope是你的视图模型,在第二种情况下它是控制器实例本身。