angularjs - 如何在 AngularJS 中将一个 Controller 注入(inject)另一个 Controller

标签 angularjs angularjs-scope angularjs-controller

我是 Angular 新手,正在尝试弄清楚如何做事......

使用 AngularJS,如何注入(inject)一个 Controller 以在另一个 Controller 中使用?

我有以下代码片段:

var app = angular.module("testApp", ['']);

app.controller('TestCtrl1', ['$scope', function ($scope) {
    $scope.myMethod = function () {
        console.log("TestCtrl1 - myMethod");
    }
}]);

app.controller('TestCtrl2', ['$scope', '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

我是否应该尝试在另一个 Controller 中使用一个 Controller ,或者我应该将其作为一项服务?

最佳答案

如果您的目的是获取另一个组件的已实例化的 Controller ,并且如果您遵循基于组件/指令的方法,那么您始终可以需要来自另一个组件的 Controller (组件的实例)遵循一定层次结构的组件。

例如:

//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.

<小时/> <小时/>

旧答案:

您需要注入(inject)$controller在另一个 Controller 中实例化一个 Controller 的服务。但请注意,这可能会导致一些设计问题。您始终可以创建遵循单一职责的可重用服务,并根据需要将它们注入(inject) 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 实例上。

如果您共享 Controller ,那么最好这样做:-

.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 实际上是您的 View 模型,在第二种情况下,它是 Controller 实例本身。

关于angularjs - 如何在 AngularJS 中将一个 Controller 注入(inject)另一个 Controller ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25417162/

相关文章:

javascript - AngularJS:在 ng-repeat 内调用 Controller 函数

javascript - angularjs指令 Controller $element

angularjs - AngularJS 中 Controller 声明的区别

angularjs - 更改输入约束后如何更新 AngularJS 中的表单 Controller

html - Angular 指令不适用于输入类型 ="number"

angularjs - Dragula angular 如何访问模型项

angularjs - 你如何设置 go 服务器以与 AngularJS html5mode 兼容?

angularjs - 当父作用域为 true 或独立时,无法访问子指令中父指令的作用域属性

angularjs - 使用ng-model时Angular JS从 Controller 清空表单输入字段

javascript - 指令中的 $watch 不会捕获范围值更改