Como posso chamar a função definida no controlador a partir de qualquer local da página da web (fora do componente do controlador)?
Funciona perfeitamente quando pressiono o botão "obter". Mas eu preciso chamá-lo de fora do controlador div. A lógica é: por padrão, minha div está oculta. Em algum lugar do menu de navegação, pressiono um botão e ele deve mostrar () minha div e executar a função "get". Como eu posso conseguir isso?
Minha página da web é:
<div ng-controller="MyController">
<input type="text" ng-model="data.firstname" required>
<input type='text' ng-model="data.lastname" required>
<form ng-submit="update()"><input type="submit" value="update"></form>
<form ng-submit="get()"><input type="submit" value="get"></form>
</div>
Meus js:
function MyController($scope) {
// default data and structure
$scope.data = {
"firstname" : "Nicolas",
"lastname" : "Cage"
};
$scope.get = function() {
$.ajax({
url: "/php/get_data.php?",
type: "POST",
timeout: 10000, // 10 seconds for getting result, otherwise error.
error:function() { alert("Temporary error. Please try again...");},
complete: function(){ $.unblockUI();},
beforeSend: function(){ $.blockUI()},
success: function(data){
json_answer = eval('(' + data + ')');
if (json_answer){
$scope.$apply(function () {
$scope.data = json_answer;
});
}
}
});
};
$scope.update = function() {
$.ajax({
url: "/php/update_data.php?",
type: "POST",
data: $scope.data,
timeout: 10000, // 10 seconds for getting result, otherwise error.
error:function() { alert("Temporary error. Please try again...");},
complete: function(){ $.unblockUI();},
beforeSend: function(){ $.blockUI()},
success: function(data){ }
});
};
}
get()
MyController a partir de outro controlador?Respostas:
Aqui está uma maneira de chamar a função do controlador de fora dela:
onde
get()
é uma função do seu controlador.Você pode mudar
para
Se você estiver usando jQuery.
Além disso, se sua função significa alterar alguma coisa na sua Visualização, você deve chamar
para aplicar as alterações.
Mais uma coisa, você deve observar que os escopos são inicializados após o carregamento da página, portanto, métodos de chamada fora do escopo sempre devem ser feitos após o carregamento da página. Caso contrário, você não chegará ao escopo.
ATUALIZAR:
Com as versões mais recentes do angular, você deve usar
E sim, isso é, de fato, uma prática ruim , mas às vezes você só precisa de coisas feitas de maneira rápida e suja.
fonte
$apply
peça funcionasse para mim, até envolver o código em uma função, por exemplo..scope.$apply(function() { scope.get() });
angular.element(document.getElementById('yourControllerElementID')).scope().controller;
For ex. if use:angular.element(document.getElementById('controller')).scope().get()
lança e erro indefinido, mas se eu usá-angular.element(document.getElementById('controller')).scope().controller.get()
lo funciona.scope()
noangular.element(...)
, porque ele retorna indefinido e um vardump do elemento / objeto angular diz que a funçãoscope
está localizada dentro do__proto__
objeto-.Eu encontrei um exemplo na internet.
Um cara escreveu esse código e funcionou perfeitamente
HTML
JAVASCRIPT
Demo
* Fiz algumas modificações, veja o original: font JSfiddle
fonte
A solução
angular.element(document.getElementById('ID')).scope().get()
parou de funcionar para mim no angular 1.5.2. Sombody menciona em um comentário que isso também não funciona na versão 1.4.9. Corrigi-o armazenando o escopo em uma variável global:chamada do código personalizado:
se você deseja restringir o escopo apenas a este método. Minimizar a exposição de todo o escopo. use a seguinte técnica.
chamada do código personalizado:
fonte
A resposta de Dmitry funciona bem. Acabei de fazer um exemplo simples usando a mesma técnica.
jsfiddle: http://jsfiddle.net/o895a8n8/5/
.
fonte
Prefiro incluir a fábrica como dependências dos controladores do que injetar sua própria linha de código: http://jsfiddle.net/XqDxG/550/
ControllerZero. $ Inject = ['$ scope', 'mySharedService'];fonte
Pode valer a pena considerar se ter o seu menu sem escopo associado é o caminho certo a seguir. Não é realmente o caminho angular.
Mas, se for o caminho que você precisa seguir, poderá fazê-lo adicionando as funções ao $ rootScope e, nessas funções, usando $ broadcast para enviar eventos. seu controlador usa $ on para ouvir esses eventos.
Outra coisa a considerar se você acabar tendo seu menu sem escopo é que, se você tiver várias rotas, todos os seus controladores precisarão ter suas próprias atualizações e obter funções. (isso pressupõe que você tenha vários controladores)
fonte
Eu uso para trabalhar com $ http, quando um deseja obter algumas informações de um recurso, faço o seguinte:
E o código no controlador:
Envio para o serviço que função tem que chamar no controlador
fonte
Como tenho várias rotas e vários controladores, não consegui obter a resposta aceita para funcionar. Eu descobri que adicionar a função à janela funciona:
Então, fora do controlador, isso pode ser feito:
fonte
Chame a função Âmbito Angular de fora do controlador.
fonte
Eu sou um usuário da estrutura Ionic e o que eu achei que forneceria consistentemente o escopo $ do controlador atual é:
angular.element(document.querySelector('ion-view[nav-view="active"]')).scope()
Suspeito que isso possa ser modificado para se ajustar à maioria dos cenários, independentemente da estrutura (ou não), localizando a consulta que terá como alvo os elementos DOM específicos que estão disponíveis apenas durante uma determinada instância do controlador.
fonte