Korzystam z AngularJS do tworzenia formantów HTML, które współdziałają ze starszą aplikacją Flex. Wszystkie wywołania zwrotne z aplikacji Flex muszą być dołączone do okna DOM.
Na przykład (w AS3)
ExternalInterface.call("save", data);
Zadzwonię
window.save = function(data){
// want to update a service
// or dispatch an event here...
}
Z poziomu funkcji zmiany rozmiaru JS chciałbym wywołać zdarzenie, które kontroler może usłyszeć. Wydaje się, że najlepiej jest stworzyć usługę. Czy możesz zaktualizować usługę spoza AngularJS? Czy kontroler może nasłuchiwać zdarzeń z usługi? W jednym eksperymencie (kliknij, aby zobaczyć skrzypce) zrobiłem to, wydaje się, że mogę uzyskać dostęp do usługi, ale aktualizacja danych usługi nie jest odzwierciedlona w widoku (w przykładzie <option>
należy dodać<select>
).
Dzięki!
var injector = angular.injector(['ng', 'MyApp']);
. Dzięki temu uzyskasz zupełnie nowy kontekst i duplikatmyService
. Oznacza to, że otrzymasz dwa wystąpienia usługi i modelu i dodasz dane w niewłaściwe miejsce. Zamiast tego należy kierować element za pomocą aplikacjiangular.element('#ng-app').injector(['ng', 'MyApp'])
. W tym momencie możesz użyć $ Apply, aby zawinąć zmiany modelu.Odpowiedzi:
Interakcja spoza kąta do kąta jest taka sama jak debugowanie aplikacji kątowej lub integracja z biblioteką strony trzeciej.
W przypadku dowolnego elementu DOM możesz to zrobić:
angular.element(domElement).scope()
aby uzyskać bieżący zakres dla elementuangular.element(domElement).injector()
aby uzyskać bieżący aplikatorangular.element(domElement).controller()
zdobyćng-controller
instancję.Z wtryskiwacza można uzyskać dostęp do dowolnej usługi w aplikacji kątowej. Podobnie z zakresu można wywoływać dowolne metody, które zostały do niego opublikowane.
Należy pamiętać, że wszelkie zmiany w modelu kątowym lub wszelkie wywołania metod w zakresie muszą być opakowane w
$apply()
następujący sposób:źródło
[ng-app]
angular.element(document.getElementById(divName)).scope()
, ale nie jestem w stanie wywoływać z niego żadnych funkcji, po prostu zwraca „niezdefiniowane” w konsoli.Misko podało prawidłową odpowiedź (oczywiście), ale niektórzy z nas początkujących mogą potrzebować jej dalszego uproszczenia.
Jeśli chodzi o wywoływanie kodu AngularJS ze starszych aplikacji, pomyśl o kodzie AngularJS jako o „mikro aplikacji” istniejącej w chronionym kontenerze w starszej aplikacji. Nie możesz bezpośrednio do niego dzwonić (z bardzo dobrego powodu), ale możesz wykonywać połączenia zdalne za pomocą obiektu $ scope.
Aby użyć obiektu $ scope, musisz uzyskać uchwyt $ scope. Na szczęście jest to bardzo łatwe do zrobienia.
Możesz użyć identyfikatora dowolnego elementu HTML w swoim „mikro-aplikacji” HTML AngularJS, aby uzyskać uchwyt zakresu $ aplikacji AngularJS.
Jako przykład załóżmy, że chcemy wywołać kilka funkcji w naszym kontrolerze AngularJS, takich jak sayHi () i sayBye (). W AngularJS HTML (widok) mamy div z identyfikatorem „MySuperAwesomeApp”. Możesz użyć następującego kodu w połączeniu z jQuery, aby uzyskać uchwyt $ scope:
Teraz możesz wywoływać funkcje kodu AngularJS za pomocą uchwytu zakresu:
Aby było wygodniej, możesz użyć funkcji, aby chwycić uchwyt lunety w dowolnym momencie, aby uzyskać do niego dostęp:
Twoje połączenia wyglądałyby następująco:
Możesz zobaczyć działający przykład tutaj:
http://jsfiddle.net/peterdrinnan/2nPnB/16/
Pokazałem to również w pokazie slajdów dla grupy Ottawa AngularJS (wystarczy przejść do ostatnich 2 slajdów)
http://www.slideshare.net/peterdrinnan/angular-for-legacyapps
źródło
<input type="button" onclick="angular.element(this).scope().edit.delete();" value="delete">
Najlepsze wyjaśnienie koncepcji, którą znalazłem, znajduje się tutaj: https://groups.google.com/forum/#!msg/angular/kqFrwiysgpA/eB9mNbQzcHwJ
Aby zaoszczędzić kliknięcie:
źródło
id
w górnym elemencie HTML, a następnie zrobićdocument.getElementById()
ten identyfikator. To daje dostęp do zakresu tego kontrolera. metody / właściwości itp. ... po prostu podkreślając komentarz goosemanjacka.W nawiązaniu do innych odpowiedzi. Jeśli nie chcesz uzyskać dostępu do metody w kontrolerze, ale chcesz uzyskać bezpośredni dostęp do usługi, możesz zrobić coś takiego:
źródło
Dzięki poprzedniej wiadomości mogę zaktualizować mój model za pomocą zdarzenia asynchronicznego.
Deklaruję mój model
I aktualizuję mój model spoza mojego zakresu
źródło
Bardziej bezpiecznym i wydajniejszym sposobem, zwłaszcza gdy dane debugowania są wyłączone, jest użycie zmiennej współdzielonej do przechowywania funkcji zwrotnej. Twój kontroler kątowy implementuje tę funkcję, aby zwrócić swoje elementy wewnętrzne do kodu zewnętrznego.
Uogólniona jako dyrektywa wielokrotnego użytku:
Stworzyłem dyrektywę „exposeScope”, która działa w podobny sposób, ale jej użycie jest prostsze:
Przechowuje to aktualny zakres (przypisany do funkcji link dyrektywy) w globalnym obiekcie „scopes”, który jest uchwytem dla wszystkich zakresów. Wartość podana w atrybucie dyrektywy jest używana jako nazwa właściwości zakresu w tym obiekcie globalnym.
Zobacz demo tutaj . Jak pokazałem w wersji demo, możesz wyzwalać zdarzenia jQuery, gdy zakres jest przechowywany i usuwany z globalnego obiektu „zakresów”.
Zauważ, że nie testowałem on („scopeDestroyed”), gdy rzeczywisty element jest usuwany z DOM. Jeśli to nie pomoże, wyzwalanie zdarzenia w samym dokumencie zamiast elementu może pomóc. (patrz skrypt app.js) w plunkerze demo.
źródło
Wiem, że to stare pytanie, ale ostatnio szukałem opcji, aby to zrobić, więc pomyślałem, że umieściłem tutaj moje odkrycia na wypadek, gdyby były przydatne dla każdego.
W większości przypadków, jeśli istnieje potrzeba, aby zewnętrzny starszy kod współdziałał ze stanem interfejsu użytkownika lub wewnętrznym działaniem aplikacji, usługa może być przydatna do usunięcia tych zmian. Jeśli zewnętrzny kod oddziałuje bezpośrednio z kontrolerem kątowym, komponentem lub dyrektywą, mocno łączysz swoją aplikację ze starszym kodem, co jest złą wiadomością.
W moim przypadku użyłem kombinacji globali dostępnych w przeglądarce (tj. Okna) i obsługi zdarzeń. Mój kod ma inteligentny silnik generowania formularzy, który wymaga danych wyjściowych JSON z CMS do inicjalizacji formularzy. Oto co zrobiłem:
Usługa schematu formularza jest tworzona za pomocą kątowego wtryskiwacza zgodnie z oczekiwaniami:
A w moich kontrolerach: function () {'use strict';
Do tej pory jest to programowanie zorientowane na usługi oparte na języku i javascript. Ale integracja starszych wersji jest tutaj:
Oczywiście każde podejście ma swoje zalety i wady. Zalety i zastosowanie tego podejścia zależy od interfejsu użytkownika. Poprzednio sugerowane podejścia nie działają w moim przypadku, ponieważ mój schemat formularza i starszy kod nie mają kontroli i znajomości zakresów kątowych. Stąd konfigurowanie aplikacji w oparciu o
angular.element('element-X').scope();
może potencjalnie uszkodzić aplikację, jeśli zmienimy zakresy. Ale jeśli Twoja aplikacja ma wiedzę na temat zakresu i może polegać na tym, że nie zmienia się często, sugerowane wcześniej podejście jest realne.Mam nadzieję że to pomoże. Wszelkie opinie są również mile widziane.
źródło