如何在AngularJS中将控制器注入另一个控制器

前端之家收集整理的这篇文章主要介绍了如何在AngularJS中将控制器注入另一个控制器前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我是新来的Angular,试图找出如何做事情…

使用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>

有很多方法可以设置require

(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是你的视图模型,在第二种情况下它是控制器实例本身。

猜你在找的Angularjs相关文章