別のコンポーネントのすでにインスタンス化されたコントローラーを取得することが目的であり、コンポーネント/ディレクティブベースのアプローチに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を設定する方法はたくさんあります。
(接頭辞なし)-現在の要素で必要なコントローラーを見つけます。見つからない場合はエラーをスローします。
?-必要なコントローラーを見つけるか、見つからない場合はリンクfnにnullを渡そうとします。
^-要素とその親を検索して、必要なコントローラーを見つけます。見つからない場合はエラーをスローします。
^^-要素の親を検索して、必要なコントローラーを見つけます。見つからない場合はエラーをスローします。
?^-要素とその親を検索して必要なコントローラーを見つけるか、見つからない場合はリンクfnにnullを渡します。
?^^-要素の親を検索して必要なコントローラを見つけるか、見つからない場合はリンクfnにnullを渡します。
古い答え:
$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
代わりにサービスに変更する必要があります。