Estou usando o AngularJS para criar controles HTML que interagem com um aplicativo Flex herdado. Todos os retornos de chamada do aplicativo Flex devem ser anexados à janela DOM.
Por exemplo (no AS3)
ExternalInterface.call("save", data);
Chamará
window.save = function(data){
// want to update a service
// or dispatch an event here...
}
De dentro da função de redimensionamento JS, eu gostaria de despachar um evento que um controlador possa ouvir. Parece que a criação de um serviço é o caminho a percorrer. Você pode atualizar um serviço de fora do AngularJS? Um controlador pode escutar eventos de um serviço? Em um experimento (clique para violino) , consegui acessar um serviço, mas a atualização dos dados do serviço não é refletida na exibição (no exemplo, um <option>
deve ser adicionado ao <select>
).
Obrigado!
var injector = angular.injector(['ng', 'MyApp']);
. Fazer isso fornecerá um contexto completamente novo e uma duplicatamyService
. Isso significa que você terminará com duas instâncias do serviço e modelo e adicionará dados ao lugar errado. Em vez disso, você deve segmentar um elemento no aplicativo usandoangular.element('#ng-app').injector(['ng', 'MyApp'])
. Nesse ponto, você pode usar $ apply para quebrar as alterações do modelo.Respostas:
A interoperabilidade de fora de angular para angular é o mesmo que depurar aplicativos angulares ou integrar-se à biblioteca de terceiros.
Para qualquer elemento DOM, você pode fazer isso:
angular.element(domElement).scope()
para obter o escopo atual do elementoangular.element(domElement).injector()
para obter o injetor de aplicativo atualangular.element(domElement).controller()
para se apossar dang-controller
instância.No injetor, você pode obter qualquer serviço em aplicação angular. Da mesma forma, no escopo, você pode invocar qualquer método que tenha sido publicado nele.
Lembre-se de que quaisquer alterações no modelo angular ou invocações de métodos no escopo precisam ser agrupadas da
$apply()
seguinte maneira:fonte
[ng-app]
nó raiz parece retroceder quando eu já tenho uma referência ao módulo ...angular.element(document.getElementById(divName)).scope()
, mas não consigo invocar nenhuma função, apenas retorna "indefinido" no console.Misko deu a resposta correta (obviamente), mas alguns de nós, novatos, talvez precisemos mais dela.
Quando se trata de chamar o código AngularJS a partir de aplicativos herdados, pense no código AngularJS como um "micro aplicativo" existente em um contêiner protegido em seu aplicativo herdado. Você não pode fazer chamadas diretamente (por uma boa razão), mas pode fazer chamadas remotas por meio do objeto $ scope.
Para usar o objeto $ scope, você precisa obter o identificador de $ scope. Felizmente, isso é muito fácil de fazer.
Você pode usar a identificação de qualquer elemento HTML no HTML do seu "micro-aplicativo" AngularJS para obter o controle do escopo $ do aplicativo AngularJS.
Como exemplo, digamos que queremos chamar algumas funções em nosso controlador AngularJS, como sayHi () e sayBye (). No HTML do AngularJS (exibição), temos uma div com o ID "MySuperAwesomeApp". Você pode usar o seguinte código, combinado com o jQuery, para obter o identificador do $ scope:
Agora você pode chamar suas funções de código AngularJS por meio do identificador de escopo:
Para tornar as coisas mais convenientes, você pode usar uma função para agarrar o manipulador de escopo a qualquer momento que desejar acessá-lo:
Suas chamadas seriam assim:
Você pode ver um exemplo de trabalho aqui:
http://jsfiddle.net/peterdrinnan/2nPnB/16/
Também mostrei isso em uma apresentação de slides para o grupo Ottawa AngularJS (apenas pule para os últimos 2 slides)
http://www.slideshare.net/peterdrinnan/angular-for-legacyapps
fonte
<input type="button" onclick="angular.element(this).scope().edit.delete();" value="delete">
A melhor explicação do conceito que encontrei está aqui: https://groups.google.com/forum/#!msg/angular/kqFrwiysgpA/eB9mNbQzcHwJ
Para economizar o clique:
fonte
id
no elemento HTML superior, em seguida, fazerdocument.getElementById()
esse ID. Isso fornece acesso ao escopo desse controlador. métodos / propriedades etc ... apenas colocando um ponto no comentário de goosemanjack.Além das outras respostas. Se você não deseja acessar um método em um controlador, mas deseja acessar o serviço diretamente, pode fazer algo assim:
fonte
Graças à postagem anterior, posso atualizar meu modelo com um evento assíncrono.
Eu declaro meu modelo
E eu atualizo meu modelo de fora do meu escopo
fonte
Uma maneira mais segura e de desempenho, especialmente quando os dados de depuração estão desativados, é usar uma variável compartilhada para manter uma função de retorno de chamada. Seu controlador angular implementa esta função para retornar seus internos ao código externo.
Generalizada como uma diretiva reutilizável:
Criei uma diretiva 'exposeScope' que funciona de maneira semelhante, mas o uso é mais simples:
Isso armazena o escopo atual (que é fornecido à função de link da diretiva) em um objeto global de 'escopos' que é detentor de todos os escopos. O valor fornecido ao atributo de diretiva é usado como o nome da propriedade do escopo neste objeto global.
Veja a demonstração aqui . Como mostrei na demonstração, é possível disparar eventos jQuery quando o escopo é armazenado e removido do objeto global 'escopos'.
Observe que, eu não testei o on ('scopeDestroyed') quando o elemento real é removido do DOM. Se não funcionar, acionar o evento no próprio documento em vez do elemento pode ajudar. (veja o app.js) no plunker de demonstração.
fonte
Sei que essa é uma pergunta antiga, mas eu estava procurando opções para fazer isso recentemente, então pensei em colocar minhas descobertas aqui, caso sejam úteis para alguém.
Na maioria dos casos, se houver a necessidade de código legado externo para interagir com o estado da interface do usuário ou com o funcionamento interno do aplicativo, um serviço pode ser útil para abstrair essas alterações. Se um código externo estiver interagindo diretamente com seu controlador angular, componente ou diretiva, você estará acoplando fortemente seu aplicativo ao código legado, o que é uma má notícia.
O que acabei usando no meu caso é uma combinação de globais acessíveis pelo navegador (janela) e manipulação de eventos. Meu código tem um mecanismo de geração de formulários inteligente que requer saída JSON de um CMS para iniciar os formulários. Aqui está o que eu fiz:
O Serviço de Esquema de Formulário é criado usando o injetor angular conforme o esperado:
E nos meus controladores: function () {'use strict';
Até agora, isso é pura programação orientada a serviços angular e javascript. Mas a integração herdada vem aqui:
Obviamente, toda abordagem tem seus méritos e desvantagens. As vantagens e o uso dessa abordagem dependem da sua interface do usuário. As abordagens sugeridas anteriormente não funcionam no meu caso, pois meu esquema de formulário e código legado não têm controle e conhecimento de escopos angulares. Portanto, a configuração do meu aplicativo com base em
angular.element('element-X').scope();
poderia potencialmente interromper o aplicativo se alterarmos os escopos. Mas se o seu aplicativo tem conhecimento do escopo e pode confiar que ele não muda com frequência, o sugerido anteriormente é uma abordagem viável.Espero que isto ajude. Qualquer feedback também é bem-vindo.
fonte