Jak działa powiązanie danych w AngularJS?

Jak działa powiązanie danych w frameworku AngularJS?

Nie znalazłem szczegółów technicznych na ich stronie . Mniej lub bardziej jasne jest, jak to działa, gdy dane są propagowane z widoku do modelu. Ale w jaki sposób AngularJS śledzi zmiany właściwości modelu bez setterów i getterów?

Odkryłem, że istnieją obserwatorzy JavaScript , którzy mogą wykonać tę pracę. Nie są one jednak obsługiwane w Internet Explorer 6 i Internet Explorer 7 . Więc jak AngularJS wiem, że zmieniłem na przykład następujące i odzwierciedlenie tej zmiany w widoku?

myobject.myproperty="new value";
Author: Community, 2012-03-13

14 answers

AngularJS zapamiętuje wartość i porównuje ją z poprzednią wartością. To jest podstawowe sprawdzanie brudu. Jeżeli nastąpiła zmiana wartości, wtedy zostanie wywołane zdarzenie change.

Metoda $apply(), którą nazywamy przechodząc ze świata nie-AngularJS do świata AngularJS, wywołuje $digest(). Trawienie to zwykłe, brudne sprawdzanie. Działa na wszystkich przeglądarkach i jest całkowicie przewidywalny.

Do kontrastu dirty-checking (AngularJS) vs change listeners ( KnockoutJS i kręgosłup.js): podczas gdy brudne sprawdzanie może wydawać się proste, a nawet nieefektywne( zajmę się tym później), okazuje się, że jest semantycznie poprawne przez cały czas, podczas gdy słuchacze zmian mają wiele dziwnych przypadków narożnych i potrzebują rzeczy takich jak śledzenie zależności, aby uczynić je bardziej semantycznie poprawnymi. KnockoutJS dependency tracking jest sprytną funkcją problemu, którego AngularJS nie ma.

Problemy ze zmianą słuchaczy:

  • składnia jest okropna, ponieważ przeglądarki nie obsługują go natywnie. Tak, istnieją proxy, ale nie są one poprawne semantycznie we wszystkich przypadkach i oczywiście nie ma proxy na starych przeglądarkach. Najważniejsze jest to, że dirty-checking pozwala robić POJO , podczas gdy KnockoutJS i Backbone.js wymusza dziedziczenie po ich klasach i dostęp do danych za pośrednictwem accesorów.
  • Zmień koalescencję. Załóżmy, że masz tablicę elementów. Powiedz, że chcesz dodać elementy do tablicy, ponieważ robisz pętlę, aby dodać, każdy po dodaniu uruchamiasz zdarzenia przy zmianie, czyli renderowaniu interfejsu użytkownika. To jest bardzo złe dla wydajności. Chcesz zaktualizować interfejs tylko raz, na końcu. Zmiany są zbyt drobnoziarniste.
  • Zmiana słuchaczy uruchamia się natychmiast na seterze, co jest problemem, ponieważ słuchacz zmiany może dalej zmieniać dane, co uruchamia więcej zdarzeń zmiany. Jest to złe, ponieważ na stosie może mieć kilka zdarzeń zmiany dzieje się na raz. Załóżmy, że masz dwie tablice, które muszą być utrzymywane w synchronizacji z jakiegokolwiek powodu. Możesz tylko dodać do jednego lub drugiego, ale za każdym razem, gdy dodajesz, odpalasz zdarzenie zmiany, które teraz ma niespójne spojrzenie na świat. Jest to bardzo podobny problem do blokowania wątków, którego JavaScript unika, ponieważ każde wywołanie zwrotne jest wykonywane wyłącznie I do zakończenia. Zdarzenia zmiany przerywają to, ponieważ setery mogą mieć daleko idące konsekwencje, które nie są zamierzone i nieoczywiste, co stwarza problem wątku na nowo. Okazuje się, że to, czego chcesz aby to zrobić, należy opóźnić wykonanie detektora i zagwarantować, że tylko jeden detektor działa na raz, stąd każdy kod może dowolnie zmieniać Dane i wie, że żaden inny kod nie działa podczas tego procesu.

A co z występem?

Więc może się wydawać, że jesteśmy powolni, ponieważ brudne sprawdzanie jest nieefektywne. W tym miejscu musimy przyjrzeć się liczbom rzeczywistym, a nie tylko teoretycznym argumentom, ale najpierw zdefiniujmy pewne ograniczenia.

Ludzie są:

  • Slow - Wszystko szybciej niż 50 ms jest niedostrzegalne dla ludzi i dlatego może być uważane za "natychmiastowe".

  • Limited - nie możesz pokazać człowiekowi więcej niż około 2000 informacji na jednej stronie. Coś więcej niż to jest naprawdę zły interfejs użytkownika, a ludzie i tak nie mogą tego przetworzyć.

Więc prawdziwe pytanie brzmi: ile porównań można zrobić na przeglądarce w 50 ms? To jest trudne pytanie do odpowiedz, ponieważ wiele czynników wchodzi w grę, ale tutaj jest przypadek testowy: http://jsperf.com/angularjs-digest/6 , który tworzy 10 000 obserwatorów. W nowoczesnej przeglądarce zajmuje to mniej niż 6 ms. Na Internet Explorer 8 zajmuje to około 40 ms. jak widać, nie jest to problem nawet w wolnych przeglądarkach w dzisiejszych czasach. Jest zastrzeżenie: porównania muszą być proste, aby zmieścić się w terminie... Niestety zbyt łatwo jest dodać powolne porównanie do AngularJS, więc łatwo jest zbudować powolne aplikacje, gdy nie wiesz, co robisz. Mamy jednak nadzieję, że uzyskamy odpowiedź, dostarczając moduł oprzyrządowania, który pokaże ci, które są powolnymi porównaniami.

Okazuje się, że gry wideo i GPU używają podejścia sprawdzania brudu, szczególnie dlatego, że jest spójne. Tak długo, jak przekroczą częstotliwość odświeżania monitora (zazwyczaj 50-60 Hz lub co 16,6-20 ms), każda wydajność powyżej tego jest marnotrawstwem, więc lepiej rysować więcej rzeczy niż uzyskiwać FPS wyżej.

 2673
Author: Misko Hevery,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-20 21:39:47

Misko już podał doskonały opis działania wiązań danych, ale chciałbym dodać mój pogląd na problem wydajności z wiązaniem danych.

Jak stwierdził Misko, około 2000 wiązań jest miejscem, w którym zaczyna się dostrzegać problemy, ale i tak nie powinieneś mieć więcej niż 2000 informacji na stronie. Może to być prawda, ale nie każde powiązanie danych jest widoczne dla użytkownika. Po rozpoczęciu budowy dowolnego rodzaju widżetu lub siatki danych z dwukierunkowym wiązaniem możesz łatwo hit 2000 wiązań, bez złego ux.

Rozważ na przykład combobox, w którym możesz wpisać tekst, aby filtrować dostępne opcje. Ten rodzaj sterowania może mieć ~150 elementów i nadal być bardzo użyteczny. Jeśli ma jakąś dodatkową funkcję (na przykład konkretną klasę na aktualnie wybranej opcji), zaczynasz dostawać 3-5 wiązań na opcję. Umieść trzy z tych widżetów na stronie (np. jeden, aby wybrać kraj, drugi, aby wybrać miasto w danym kraju, a trzeci, aby wybrać hotel) a Ty jesteś już gdzieś między 1000 a 2000 wiązań.

Lub rozważ siatkę danych w korporacyjnej aplikacji internetowej. 50 wierszy na stronę nie jest nieuzasadnione, z których każdy może mieć 10-20 kolumn. Jeśli zbudujesz to z ng-repeats i / lub masz informacje w niektórych komórkach, które używają niektórych wiązań, możesz zbliżyć się do 2000 wiązań za pomocą samej siatki.

Uważam, że jest to ogromny problem podczas pracy z AngularJS, a jedyne rozwiązanie, jakie udało mi się znaleźć do tej pory jest konstruowanie widżetów bez użycia dwukierunkowego wiązania, zamiast tego za pomocą ngOnce, deregisting watchers i podobnych sztuczek, lub konstruowanie dyrektyw, które budują DOM z jQuery i manipulacją DOM. Wydaje mi się, że to nie jest cel używania Angular.

Chciałbym usłyszeć sugestie dotyczące innych sposobów radzenia sobie z tym, ale może powinienem napisać własne pytanie. Chciałem to umieścić w komentarzu, ale okazało się, że jest to o wiele za długie dla to...

TL; DR
Powiązanie danych może powodować problemy z wydajnością na złożonych stronach.

 310
Author: MW.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-22 13:28:36

Przez brudne sprawdzenie $scope obiektu

Angular utrzymuje prostą array obserwatorów w obiektach $scope. Jeśli sprawdzisz dowolny $scope okaże się, że zawiera on array o nazwie $$watchers.

Każdy obserwator jest object, który zawiera między innymi

  1. wyrażenie, które obserwator monitoruje. To może być tylko attribute nazwa, lub coś bardziej skomplikowanego.
  2. Ostatnia znana wartość wyrażenia. Można to sprawdzić pod prąd obliczona wartość wyrażenia. Jeśli wartości różnią się, kontroler uruchomi funkcję i oznacz $scope jako brudne.
  3. funkcja, która zostanie wykonana, jeśli obserwator jest brudny.

Jak definiuje się obserwatorów

Istnieje wiele różnych sposobów definiowania obserwatora w AngularJS.
  • Możesz jawnie $watch an attribute na $scope.

    $scope.$watch('person.username', validateUnique);
    
  • Możesz umieścić interpolację {{}} w szablonie (obserwator będzie stworzony dla Ciebie na bieżącym $scope).

    <p>username: {{person.username}}</p>
    
  • Możesz poprosić dyrektywę taką jak ng-model o zdefiniowanie obserwatora dla Ciebie.

    <input ng-model="person.username" />
    

Cykl $digest sprawdza wszystkich obserwatorów pod względem ich ostatniej wartości

Kiedy wchodzimy w interakcję z AngularJS poprzez normalne kanały (ng-model, ng-repeat, itp.), cykl trawienia zostanie uruchomiony przez dyrektywę.

Cykl digest jest głębokość-pierwszy Trawers $scope i wszystkich jego dzieci . Dla każdego $scope object, iterujemy nad jego $$watchers array i oceń wszystkie wyrażenia. Jeśli wartość nowego wyrażenia różni się od ostatniej znanej wartości, wywoływana jest funkcja obserwatora. Ta funkcja może przekompilować część DOM, przekompilować wartość na $scope, wywołać AJAX request, wszystko, czego potrzebujesz.

Każdy zakres jest przesuwany, a każde wyrażenie zegarka jest oceniane i sprawdzane pod ostatnią wartością.

Jeśli obserwator zostanie uruchomiony, {[7] } jest brudny

Jeśli funkcja obserwująca zostaje uruchomiona, aplikacja wie, że coś się zmieniło, a {[7] } jest oznaczona jako brudna.

Funkcje Watcher mogą zmieniać inne atrybuty na $scope lub na rodzicu $scope. Jeśli jedna funkcja $watcher została uruchomiona, nie możemy zagwarantować, że nasze pozostałe $scopes są nadal czyste, więc wykonujemy cały cykl digest ponownie.

Dzieje się tak dlatego, że AngularJS ma dwukierunkowe powiązanie, więc dane mogą być przekazywane z powrotem do drzewa $scope. Możemy zmienić wartość na wyższą $scope, która już został strawiony. Być może zmienimy wartość na $rootScope.

Jeśli $digest jest brudny, wykonujemy cały cykl$digest ponownie

Cały czas przechodzimy przez cykl $digest, aż albo cykl digest zostanie oczyszczony (wszystkie wyrażenia $watch mają taką samą wartość jak w poprzednim cyklu), albo osiągniemy limit digest. Domyślnie limit ten wynosi 10.

Jeśli osiągniemy limit digest AngularJS spowoduje błąd w konsoli:

10 $digest() iterations reached. Aborting!

The digest jest trudny dla maszyny, ale łatwy dla programisty

Jak widzisz, za każdym razem, gdy coś się zmieni w aplikacji AngularJS, AngularJS sprawdzi każdy obserwator w hierarchii $scope, aby zobaczyć, jak odpowiedzieć. Dla programisty jest to ogromne dobrodziejstwo wydajności, jak teraz trzeba napisać prawie nie kod okablowania, AngularJS po prostu zauważyć, jeśli wartość uległa zmianie, i zrobić resztę aplikacji zgodne ze zmianą.

Z perspektywy maszyny, choć jest to szalenie nieefektywne i spowolni naszą aplikację, jeśli stworzymy zbyt wielu obserwatorów. Misko zacytował liczbę około 4000 obserwatorów, zanim Twoja aplikacja poczuje się wolna w starszych przeglądarkach.

Ten limit jest łatwy do osiągnięcia, jeśli ng-repeat przez duże JSON array na przykład. Możesz temu zapobiec, korzystając z funkcji, takich jak jednorazowe powiązanie, aby skompilować szablon bez tworzenia obserwatorów.

Jak uniknąć tworzenia zbyt wielu obserwatorów

Za każdym razem, gdy użytkownik wchodzi w interakcję z aplikacją, każdy obserwator w Twojej aplikacji będzie oceniany co najmniej raz. Dużą częścią optymalizacji aplikacji AngularJS jest zmniejszenie liczby obserwatorów w drzewie $scope. Jednym z łatwych sposobów jest użycie wiązania jednorazowego .

Jeśli masz dane, które rzadko się zmieniają, możesz powiązać je tylko raz używając składni::, tak:

<p>{{::person.username}}</p>

Lub

<p ng-bind="::person.username"></p>

Powiązanie zostanie wywołane tylko po wyrenderowaniu zawierającego szablon i załadowaniu danych do $scope.

Jest to szczególnie ważne, gdy masz {[45] } z wieloma przedmiotami.
<div ng-repeat="person in people track by username">
  {{::person.username}}
</div>
 145
Author: superluminary,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-22 11:40:33

To jest moje podstawowe zrozumienie. To może być złe!

  1. elementy są obserwowane przez przekazanie funkcji (zwracanie rzeczy do obserwowanych) do metody $watch.
  2. zmiany obserwowanych elementów muszą być dokonywane w bloku kodu owinięte metodą $apply.
  3. na końcu $apply wywoływana jest Metoda $digest, która przez każdy z zegarków i kontroli, aby sprawdzić, czy zmieniły się od ostatni raz $digest biegł.
  4. jeśli zostaną znalezione jakiekolwiek zmiany, to wywoływane ponownie, dopóki wszystkie zmiany się nie ustabilizują.

W normalnym rozwoju, składnia wiążąca dane w HTML mówi kompilatorowi AngularJS, aby utworzył dla Ciebie Zegarki, a metody kontrolera są już uruchomione wewnątrz $apply. Tak więc dla twórcy aplikacji jest to wszystko przejrzyste.

 78
Author: Pete BD,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-06 08:02:47

Zastanawiałam się nad tym przez jakiś czas. Bez setterów jak AngularJS zauważa zmiany w obiekcie $scope? Czy to ich ankieta?

To, co właściwie robi, jest takie: każde "normalne" miejsce, w którym zmodyfikujesz model, zostało już wywołane z wnętrzności AngularJS, więc automatycznie wywołuje $apply dla ciebie po uruchomieniu kodu. Powiedzmy, że twój kontroler ma metodę podłączoną do ng-click na jakimś elemencie. Ponieważ AngularJS połączy wywołanie tej metody Razem dla Ciebie, ma szansę wykonać $apply w odpowiednie miejsce. Podobnie, dla wyrażeń, które pojawiają się bezpośrednio w widokach, są one wykonywane przez AngularJS, więc robi to $apply.

Gdy dokumentacja mówi o konieczności ręcznego wywołania $apply dla kodu poza AngularJS, mówi o kodzie, który po uruchomieniu nie pochodzi z AngularJS samego w stosie wywołań.

 59
Author: jpsimons,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-06 00:43:01

Wyjaśnienie ze zdjęciami:

Data-Binding needs a mapping

Odniesienie w zakresie nie jest dokładnie odniesieniem w szablonie. Kiedy data-bind dwa obiekty, trzeba trzeci, który nasłuchuje pierwszego i modyfikować drugi.

Tutaj wpisz opis obrazka

Tutaj, kiedy modyfikujesz <input>, dotykasz danych-ref3. A klasyczny Mechanizm data-bind zmieni data-ref4. Więc jak inne {{data}} wyrażenia będą się poruszać ?

Zdarzenia prowadzą do $digest ()

Tutaj wpisz opis obrazka

Kątowa utrzymuje oldValue i newValue każdego wiązania. I po każdym wydarzeniu kątowym, słynna pętla $digest() sprawdzi listę obserwowanych, aby sprawdzić, czy coś się zmieniło. Te zdarzenia kątowe ng-click, ng-change, $http zakończone ... $digest() będzie pętlą tak długo, jak Dowolna oldValue różni się od newValue.

Na poprzednim zdjęciu zauważy, że dane-ref1 i dane-ref2 mają zmieniony.

Wnioski

Jest trochę jak jajko i Kura. Nigdy nie wiadomo, kto zaczyna, ale mam nadzieję, że działa przez większość czasu zgodnie z oczekiwaniami.

Druga kwestia polega na tym, że możesz łatwo zrozumieć wpływ prostego wiązania na pamięć i procesor. Mam nadzieję, że pulpity są na tyle grube, by sobie z tym poradzić. Telefony komórkowe nie są tak silne.

 31
Author: Nicolas Zozol,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-16 07:36:07

Oczywiście nie ma okresowego sprawdzania Scope czy nie ma żadnych zmian w dołączonych do niego obiektach. Nie wszystkie obiekty dołączone do scope są oglądane . Scope $ $ $ . Scope przechodzi przez to $$watchers tylko wtedy, gdy wywołane jest $digest.

Angular dodaje obserwatora do $ $ obserwatorów dla każdego z nich

  1. {{wyrażenie}} - w szablonach (i wszędzie tam, gdzie jest wyrażenie) lub gdy definiujemy ng-model.
  2. $ scope.$watch('expression/function') - w JavaScript możemy po prostu dołączyć obiekt scope dla angular do watch.

$watch funkcja przyjmuje trzy parametry:

  1. Pierwszą z nich jest funkcja watcher, która po prostu zwraca obiekt lub możemy po prostu dodać wyrażenie.

  2. Druga to funkcja listener, która zostanie wywołana, gdy nastąpi zmiana w obiekcie. Wszystkie rzeczy jak Zmiany DOM zostaną zaimplementowane w tej funkcji.

  3. Trzeci jest opcjonalnym parametrem, który przyjmuje wartość logiczną . Jeśli to prawda, angular deep obserwuje obiekt , a jeśli jego fałszywy kąt po prostu obserwuje obiekt. Rough implementacja $watch wygląda tak

Scope.prototype.$watch = function(watchFn, listenerFn) {
   var watcher = {
       watchFn: watchFn,
       listenerFn: listenerFn || function() { },
       last: initWatchVal  // initWatchVal is typically undefined
   };
   this.$$watchers.push(watcher); // pushing the Watcher Object to Watchers  
};

Jest ciekawa rzecz w Angular nazwie cyklu Digest. Cykl $digest rozpoczyna się w wyniku wywołania $scope.$digest (). Załóżmy, że zmieniasz model $ scope w funkcji obsługi za pomocą dyrektywy ng-click. W takim przypadku AngularJS automatycznie uruchamia cykl $digest wywołując $digest().oprócz ng-click, istnieje kilka innych wbudowanych dyrektyw/usług, które umożliwiają zmianę modeli (np. ng-model, $timeout, itp.) i automatycznie uruchamiają cykl $digest. Szorstka implementacja $digest wygląda tak.

Scope.prototype.$digest = function() {
      var dirty;
      do {
          dirty = this.$$digestOnce();
      } while (dirty);
}
Scope.prototype.$$digestOnce = function() {
   var self = this;
   var newValue, oldValue, dirty;
   _.forEach(this.$$watchers, function(watcher) {
          newValue = watcher.watchFn(self);
          oldValue = watcher.last;   // It just remembers the last value for dirty checking
          if (newValue !== oldValue) { //Dirty checking of References 
   // For Deep checking the object , code of Value     
   // based checking of Object should be implemented here
             watcher.last = newValue;
             watcher.listenerFn(newValue,
                  (oldValue === initWatchVal ? newValue : oldValue),
                   self);
          dirty = true;
          }
     });
   return dirty;
 };

Jeśli używamy funkcji JavaScript setTimeout() do aktualizacji modelu zakresu, Angular nie wie, co możesz zmienić. W tym przypadku naszym obowiązkiem jest ręczne wywołanie $apply (), co uruchamia cykl $digest. Podobnie, jeśli masz dyrektywę, która ustawia detektor zdarzeń DOM i zmienia niektóre modele wewnątrz funkcji obsługi, musisz wywołać $apply (), aby upewnić się, że zmiany wejdą w życie. Główną ideą $apply jest to, że możemy wykonać jakiś kod, który nie jest świadomy Angular, że kod może nadal zmieniać rzeczy w zakresie. Jeśli zawijamy ten kod w $apply , zajmie się wywołaniem $digest (). Rough implementation of $apply ().

Scope.prototype.$apply = function(expr) {
       try {
         return this.$eval(expr); //Evaluating code in the context of Scope
       } finally {
         this.$digest();
       }
};
 20
Author: Sasank Sunkavalli,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-06 08:04:15

AngularJS obsługuje mechanizm wiązania danych za pomocą trzech potężnych funkcji: $watch(),$digest () i $ apply () . Przez większość czasu AngularJS wywoła $scope.$watch () I $scope.$digest (), ale w niektórych przypadkach może być konieczne ręczne wywołanie tych funkcji, aby zaktualizować je o nowe wartości.

$zegarek() :-

Ta funkcja jest używana do obserwacji zmian w zmiennej $scope. Przyjmuje trzy parametry: wyrażenie, słuchacz i obiekt równości, gdzie detektor i obiekt równości są parametrami opcjonalnymi.

$digest() -

Ta funkcja jest powtarzana przez wszystkie zegarki w obiekcie $ scope, i jego potomek $Scope objects
(jeśli ma). Kiedy $digest() iteruje nad zegarami sprawdza, czy wartość wyrażenia ma zmieniony. Jeśli wartość się zmieniła, AngularJS wywoła listener z nowa wartość i Stara wartość. Funkcja $ digest () jest called ilekroć AngularJS uzna to za konieczne. Na przykład po przycisku kliknij, lub po wywołaniu AJAX. Możesz mieć kilka przypadków, w których AngularJS nie wywołuje funkcji $digest (). W takim razie musisz sam to nazwij.

$zastosuj() -

Angular do auto-magicznie aktualizuje tylko te zmiany modelu, które są inside AngularJS context. Gdy zmienisz dowolny model poza kontekst kątowy (np. zdarzenia Dom przeglądarki, setTimeout, XHR lub third party libraries), następnie należy poinformować o zmianach przez wywołanie $apply() ręcznie. Po zakończeniu wywołania funkcji $apply() AngularJS wywołuje wewnętrznie $digest (), więc wszystkie powiązania danych są aktualizacja.

 14
Author: Bharath Kumar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-06 12:57:20

Zdarzyło się, że musiałem połączyć model danych osoby z formularzem, co zrobiłem było bezpośrednie mapowanie danych z formularzem.

Na przykład, jeśli model miał coś takiego:

$scope.model.people.name

Wejście sterujące formularza:

<input type="text" name="namePeople" model="model.people.name">

W ten sposób, jeśli zmodyfikujesz wartość kontrolera obiektu, zostanie to automatycznie odzwierciedlone w widoku.

Przykład, w którym przekazałem model jest aktualizowany z danych serwera, gdy prosisz o Kod pocztowy i Kod Pocztowy na podstawie pisane ładuje listę Kolonii i miast powiązanych z tym widokiem i domyślnie ustawia pierwszą wartość z użytkownikiem. I to działa bardzo dobrze, co się dzieje, jest to, że angularJS czasami trwa kilka sekund, aby odświeżyć model, aby to zrobić można umieścić spinner podczas wyświetlania danych.

 7
Author: gartox,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-06 08:03:30

Powiązanie danych:

co to jest powiązanie danych?

Za każdym razem, gdy użytkownik zmienia dane w widoku, następuje aktualizacja tej zmiany w modelu zakresu i viceversa.

Jak to możliwe?

Krótka odpowiedź: Z pomocą cyklu trawienia.

Opis: Angular js ustawia watcher na modelu scope, który uruchamia funkcję listener, jeśli nastąpi zmiana w model.

$scope.$watch('modelVar' , function(newValue,oldValue){

//Dom update code with new value

});

Kiedy i jak jest wywoływana funkcja watcher?

Funkcja Watcher jest wywoływana jako część cyklu digest.

Cykl Digest jest wywoływany automatycznie jako część angular JS wbudowanego w dyrektywy / usługi takie jak ng-model , ng-bind , $timeout, ng-click i inne.. to pozwala uruchomić cykl trawienia.

Cykl trawienia funkcja:

$scope.$digest() -> digest cycle against the current scope.
$scope.$apply() -> digest cycle against the parent scope 

I. e $rootScope.$apply()

Uwaga: $apply () jest równe $rootScope.$digest () oznacza to, że brudne sprawdzanie zaczyna się od głównego, górnego lub nadrzędnego zakresu w dół do wszystkich podrzędnych $zakresów w aplikacji angular JS.

Powyższe funkcje działają w przeglądarkach IE dla wymienionych wersji również po prostu upewniając się, że aplikacja jest angular JS aplikacji, co oznacza, że używasz angularjs Framework script file odwołuje się w skrypcie tag.

Dziękuję.
 6
Author: Dhana,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-05 11:38:40
  1. Jednokierunkowe powiązanie danych jest podejściem, w którym wartość jest pobierana z modelu danych i wstawiana do elementu HTML. Nie ma możliwości aktualizacji modelu z widoku. Jest stosowany w klasycznych systemach szablonów. Systemy te wiążą dane tylko w jednym kierunku.

  2. Wiązanie danych w aplikacjach Angular polega na automatycznej synchronizacji danych pomiędzy komponentami modelu i widoku.

Powiązanie danych pozwala traktować model jako jedno źródło prawdy w Twoim podanie. Widok jest projekcją modelu przez cały czas. Jeśli model zostanie zmieniony, widok odzwierciedla zmianę i odwrotnie.

 5
Author: Shankar Gangadhar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-17 19:28:45

Oto przykład powiązania danych z AngularJS, używając pola wejściowego. Wyjaśnię później

Kod HTML

<div ng-app="myApp" ng-controller="myCtrl" class="formInput">
     <input type="text" ng-model="watchInput" Placeholder="type something"/>
     <p>{{watchInput}}</p> 
</div>

Kod AngularJS

myApp = angular.module ("myApp", []);
myApp.controller("myCtrl", ["$scope", function($scope){
  //Your Controller code goes here
}]);

Jak widać w powyższym przykładzie, AngularJS używa ng-model do słuchania i oglądania tego, co dzieje się na elementach HTML, szczególnie na polach input. Kiedy coś się stanie, zrób coś. W naszym przypadku ng-model jest bind do naszego poglądu, używając notacji wąsów {{}}. Cokolwiek zostanie wpisane w polu wejściowym jest natychmiast wyświetlany na ekranie. I na tym polega piękno wiązania danych, używając AngularJS w najprostszej formie.

Mam nadzieję, że to pomoże.

Zobacz przykład pracy Tutaj na Codepen

 4
Author: AllJs,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-06 18:15:40

AngularJs obsługuje dwukierunkowe wiązanie danych.
Oznacza, że możesz uzyskać dostęp do danych View - > Controller & Controller - > View

Dla Ex.

1)

// If $scope have some value in Controller. 
$scope.name = "Peter";

// HTML
<div> {{ name }} </div>

O / P

Peter

Możesz powiązać dane w ng-model Jak:-
2)

<input ng-model="name" />

<div> {{ name }} </div>

Tutaj w powyższym przykładzie cokolwiek użytkownik wprowadzający poda, będzie widoczne w znaczniku <div>.

Jeśli chcesz powiązać wejście z html do kontroler:-
3)

<form name="myForm" ng-submit="registration()">
   <label> Name </lbel>
   <input ng-model="name" />
</form>

Tutaj jeśli chcesz użyć input name w kontrolerze, to

$scope.name = {};

$scope.registration = function() {
   console.log("You will get the name here ", $scope.name);
};

ng-model wiąże nasz pogląd i renderuje go w wyrażeniu {{ }}.
ng-model to dane, które są wyświetlane użytkownikowi w widoku i z którymi użytkownik wchodzi w interakcję.
Tak więc łatwo jest powiązać dane w AngularJs.

 4
Author: ojus kulkarni,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-13 07:58:31

Kątowe.js tworzy obserwatora dla każdego modelu, który tworzymy w widoku. Za każdym razem, gdy model jest zmieniany, do modelu dołączana jest klasa "ng-dirty", więc obserwator obserwuje wszystkie modele, które mają klasę "ng-dirty" i aktualizuje swoje wartości w kontrolerze i odwrotnie.

 3
Author: Shankar Gangadhar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-31 00:30:43