Se sua intenção é obter um controlador já instanciado de outro componente e se você está seguindo uma abordagem baseada em componente / diretiva, você pode sempre usar require
um controlador (instância de um componente) de outro componente que segue uma certa hierarquia.
Por exemplo:
//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.
},
...
});
Agora, o uso dos componentes acima pode ser algo assim:
<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>
Há muitas maneiras de configurar o require .
(sem prefixo) - Localize o controlador necessário no elemento atual. Lance um erro se não for encontrado.
? - Tente localizar o controlador necessário ou passe nulo para o link fn se não for encontrado.
^ - Localize o controlador necessário, pesquisando o elemento e seus pais. Lance um erro se não for encontrado.
^^ - Localize o controlador necessário pesquisando os pais do elemento. Lance um erro se não for encontrado.
? ^ - Tenta localizar o controlador requerido pesquisando o elemento e seus pais ou passa null para o link fn se não for encontrado.
? ^^ - Tenta localizar o controlador necessário pesquisando os pais do elemento, ou passa null para o link fn se não for encontrado.
Resposta antiga:
Você precisa injetar $controller
serviço para instanciar um controlador dentro de outro controlador. Mas esteja ciente de que isso pode levar a alguns problemas de design. Você sempre pode criar serviços reutilizáveis que seguem a responsabilidade única e injetá-los nos controladores conforme necessário.
Exemplo:
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.
}]);
Em qualquer caso, você não pode chamar TestCtrl1.myMethod()
porque anexou o método na $scope
instância do controlador e não na instância do controlador.
Se você estiver compartilhando o controlador, será sempre melhor fazer: -
.controller('TestCtrl1', ['$log', function ($log) {
this.myMethod = function () {
$log.debug("TestCtrl1 - myMethod");
}
}]);
e enquanto consome, faça:
.controller('TestCtrl2', ['$scope', '$controller', function ($scope, $controller) {
var testCtrl1ViewModel = $controller('TestCtrl1');
testCtrl1ViewModel.myMethod();
}]);
No primeiro caso, é realmente o $scope
seu modelo de visualização e, no segundo caso, é a própria instância do controlador.
TestCtrl1
para um serviço.