[javascript] Как работает привязка данных в AngularJS?



5 Answers

Misko уже дал отличное описание того, как работают привязки данных, но я хотел бы добавить свое представление о проблеме производительности с привязкой данных.

Как заявила Мишко, около 2000 привязок - это то, где вы начинаете видеть проблемы, но в любом случае вы не должны иметь более 2000 единиц информации на странице. Это может быть правдой, но не все данные привязываются к пользователю. После того, как вы начнете создавать какой-либо виджет или сетку данных с двусторонней привязкой, вы можете легко нанести 2000 привязок, не имея плохих ux.

Рассмотрим, например, combobox, где вы можете набирать текст для фильтрации доступных параметров. Такой контроль может иметь ~ 150 элементов и по-прежнему может быть очень полезен. Если у него есть дополнительная функция (например, определенный класс в выбранном в данный момент параметре), вы получаете 3-5 привязок для каждого параметра. Поместите три из этих виджетов на страницу (например, один, чтобы выбрать страну, другой - выбрать город в указанной стране, а третий - выбрать отель), и вы уже где-то между 1000 и 2000 привязками.

Или рассмотрите сетку данных в корпоративном веб-приложении. 50 строк на страницу не являются необоснованными, каждая из которых может содержать 10-20 столбцов. Если вы построите это с помощью ng-повторов и / или получите информацию в некоторых ячейках, которые используют некоторые привязки, вы можете приблизиться к 2000 привязкам только с этой сеткой.

Я считаю, что это огромная проблема при работе с AngularJS, и единственным решением, которое я смог найти до сих пор, является создание виджетов без использования двусторонней привязки, вместо этого использование ngOnce, снятие регистрации с наблюдателей и т. Д. Или построение директив который строит DOM с манипуляциями jQuery и DOM. Я чувствую, что это побеждает цель использования Углового в первую очередь.

Я хотел бы услышать предложения по другим способам справиться с этим, но тогда, возможно, я должен написать свой собственный вопрос. Я хотел поставить это в комментарии, но оказалось, что это слишком долго для этого ...

TL; DR
Связывание данных может вызвать проблемы с производительностью на сложных страницах.

Question

Как привязка данных работает в структуре AngularJS ?

Я не нашел технических деталей на их сайте . Более или менее ясно, как это работает, когда данные распространяются из представления в модель. Но как AngularJS отслеживает изменения свойств модели без сеттеров и геттеров?

Я обнаружил, что есть наблюдатели JavaScript, которые могут выполнять эту работу. Но они не поддерживаются в Internet Explorer 6 и Internet Explorer 7 . Итак, как AngularJS знает, что я изменил, например, следующее и отразил это изменение в представлении?

myobject.myproperty="new value";



AngularJS обрабатывает механизм привязки данных с помощью трех мощных функций: $watch() , $digest() и $apply() . В большинстве случаев AngularJS будет вызывать $ scope. $ Watch () и $ scope. $ Digest (), но в некоторых случаях вам может потребоваться вручную вызвать эти функции для обновления новыми значениями.

$ watch () : -

Эта функция используется для наблюдения за изменениями в переменной $ scope. Он принимает три параметра: выражение, слушатель и объект равенства, где слушатель и объект равенства являются необязательными параметрами.

$ digest () -

Эта функция выполняет итерацию через все часы в объекте $ scope и его объекты $ scope
(если он есть). Когда $ digest () выполняет итерацию по часам, он проверяет, изменилось ли значение выражения. Если значение изменилось, AngularJS вызывает слушателя с новым значением и старым значением. Функция $ digest () вызывается всякий раз, когда AngularJS считает, что это необходимо. Например, после нажатия кнопки или после вызова AJAX. У вас могут быть некоторые случаи, когда AngularJS не вызывает функцию $ digest () для вас. В этом случае вы должны называть это самостоятельно.

$ apply () -

Angular do auto-magically обновляет только те изменения модели, которые находятся внутри контекста AngularJS. Когда вы изменяете любую модель вне контекста Angular (например, события DOM в браузере, setTimeout, XHR или сторонние библиотеки), вам необходимо сообщить об Угловом изменении, вызвав $ apply () вручную. Когда вызов функции $ apply () завершает, AngularJS вызывает $ digest () внутренне, поэтому все привязки данных обновляются.




  1. Односторонняя привязка данных - это подход, в котором значение берется из модели данных и вставляется в элемент HTML. Невозможно обновить модель из представления. Он используется в классических системах шаблонов. Эти системы связывают данные только в одном направлении.

  2. Связывание данных в Угловых приложениях - это автоматическая синхронизация данных между компонентами модели и представления.

Связывание данных позволяет рассматривать модель в качестве единственного источника истины в вашем приложении. Представление - это проекция модели во все времена. Если модель изменена, представление отражает изменение и наоборот.




Объяснение с картинками:

Связывание данных требует сопоставления

Ссылка в области не является ссылкой в ​​шаблоне. Когда вы привязываете данные к двум объектам, вам нужен третий, который прослушивает первый и модифицирует другой.

Здесь, когда вы изменяете <input> , вы касаетесь данных-ref3 . И классический механизм привязки данных будет изменять данные ref4 . Итак, как будут перемещаться другие выражения {{data}} ?

События приводят к $ digest ()

Угловой поддерживает oldValue и newValue каждого привязки. И после каждого события Angular знаменитый цикл $digest() проверяет WatchList, чтобы увидеть, что-то изменилось. Эти Угловые события : ng-click , ng-change , $http completed ... $digest() будет зацикливаться до тех пор, пока любой oldValue отличается от newValue .

На предыдущем снимке он заметит, что данные ref1 и data-ref2 изменились.

Выводы

Это немного похоже на яйцо и курица. Вы никогда не знаете, кто начнет, но, надеюсь, он работает большую часть времени, как и ожидалось.

Другой момент заключается в том, что вы можете легко понять влияние глубокой простой привязки к памяти и процессору. Надеемся, что рабочие столы достаточно полны, чтобы справиться с этим. Мобильные телефоны не так сильны.




Это мое основное понимание. Это может быть неправильно!

  1. Элементы просматриваются передачей функции (возвращающей предмет, подлежащий просмотру) методу $watch .
  2. Изменения наблюдаемых элементов должны быть сделаны в блоке кода, завершенном методом $apply .
  3. В конце $apply вызывается метод $digest который проходит через каждую из часов и проверяет, изменились ли они с тех пор, как в последний раз запускался $digest .
  4. Если какие-либо изменения найдены, то дайджест вызывается снова, пока все изменения не стабилизируются.

В обычной разработке синтаксис привязки данных в HTML говорит компилятору AngularJS о создании часов для вас, а методы управления уже запущены внутри $apply . Поэтому разработчику приложения все прозрачно.




Ниже приведен пример привязки данных к AngularJS с использованием поля ввода. Я объясню позже

Код HTML

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

Код AngularJS

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

Как вы можете видеть в приведенном выше примере, AngularJS использует ng-model для прослушивания и просмотра событий, происходящих на элементах HTML, особенно в полях input . Когда что-то происходит, сделайте что-нибудь. В нашем случае ng-model привязывается к нашему представлению, используя обозначение уса {{}} . Все, что вводится внутри поля ввода, отображается на экране мгновенно. И это красота привязки данных, используя AngularJS в простейшей форме.

Надеюсь это поможет.

См. Рабочий пример здесь, на Codepen




Related