2015-07-22 2 views
4

Я так смущен, используя $scope.$digest() способ. Насколько я знаю, когда мы называем $scope.$digest() его не будет обновлять значение области родительского, так

ее обрабатывает все из наблюдателей в текущей области и ее детей

, но когда я call $scope.$digest() его также обновляет родительскую область, в этом случае $rootScope.

В следующем примере у меня есть демонстрация. В $rootScope у меня есть переменная с именем value_on_root, поэтому каждый раз, когда я вызываю событиена входе, я вызываю угловую функцию и внутри нее меняю значение переменной file_src, которое находится на $scope, а также меняю значение переменной value_on_root, который находится на $rootScope, поэтому, когда я звоню $scope.$digest, его обновление вызывает наблюдателей на $rootScope тоже.

Проверьте пример здесь

Click to see example in CODEPEN

ответ

2

Per This Article:

«за $ переваривать цикл начинается в результате вызова $ объема $ дайджеста() Предположим, что вы измените масштаб.. модель в функции обработчика через директиву ng-click. В этом случае AngularJS автоматически запускает цикл $ digest, вызывая $ digest(). Когда цикл $ digest начинается, он запускает каждого из наблюдателей. Эти наблюдатели проверяют, соответствует ли текущее значение модели области отличается от последнего рассчитанного значения. Если да, то корр. выполняется функция прослушивающего слушателя. В результате, если у вас есть какие-либо выражения в представлении, они будут обновлены. В дополнение к ng-click существует несколько других встроенных директив/сервисов, которые позволяют вам изменять модели (например, ng-model, $ timeout и т. Д.) И автоматически запускать цикл $ digest.

До сих пор так хорошо! Но есть небольшая гоча. В приведенных выше случаях Угловой не напрямую вызывает $ digest(). Вместо этого он вызывает $ scope. $ Apply(), который в свою очередь вызывает $ rootScope. $ Digest(). В результате этого цикл digest начинается с $ rootScope и затем посещает все дочерние области, вызывающие наблюдателей на этом пути. "

Переменная rootscope затем обновляется, и вы увидите изменения в вашей codepen

+0

Hi @Kreepn, спасибо за ответ, но вы не отвечаете на мой вопрос вообще, в этом ответе вы рассказываете мне о том, как цикл дайджест работает на angularjs, и я уже знаю это. Когда вы вызываете $ scope. $ Digest() обрабатывает все наблюдатели текущей области и ее дочерних элементов, поэтому, если вы видели мой пример, есть переменная, которая живет в $ rootScope, и хотя я называю $ scope. $ digest() эта переменная обновляется. – oletob

+0

@evolquez Довольно уверен, что это точный ответ на ваш вопрос. Из-за характера цепочек вызовов один вызов $ digest запускает корневой кодекс, чтобы проверить его собственные свойства. Вы вносите изменения через '$ rootScope.value_on_root =« Значение обновлено »;' и оно обновляет его соответственно в кодексе. – KreepN

+0

@evolquez Точное подобное объяснение можно найти здесь: http://stackoverflow.com/questions/12333410/why-scope-apply-calls-rootscope-digest-rather-than-this-digest – KreepN

0

Путаница проистекает из вашей интерпретации $scope.$digest ниже:.

Насколько я знаю, когда мы называем $ сфера. $ дайджест() его не обновит родительское значение сферы

значение родительской области в будет всегда обновляться при добавлении или изменить свойство для этого объекта области видимости. Это справедливо для любого объекта JS (если этот объект не был заморожен или иным образом не смог получить обновления/новые свойства, но в этом случае это не важно).

Теперь, если новое или измененное свойство этого объекта области видимости отражено в DOM, это еще одна история.

В вашем примере codepen вы корректировали корневой сферы, придав ему новое значение в контроллере, как например:

$rootScope.value_on_root = "Value updated"; 

Причина, почему это обновление отражается в DOM из-за двух вещей:

  1. Вы неявно зарегистрированы Бодрствующего для value_on_root в объекте области видимости вашего контроллера в вашем HTML ниже:

    <div><strong>{{value_on_root}}</strong></div> 
    
  2. Область вашего контроллера использует прототипное наследование, поэтому свойство value_on_root можно получить через область вашего контроллера. Understanding Scopes - отличная статья, объясняющая наследование сферы в AngularJS. Из статьи:

    Если попытаться получить доступ к свойству, определенное на parentScope от ребенка рамки, JavaScript будет первым смотреть в детской сфере, не найти недвижимость, то смотрите в унаследованной сфере, и найти имущество. (Если он не нашел свойство в parentScope, он продолжит цепочку прототипов ... вплоть до области корня).

В вашем примере, потому что у вас есть value_on_root Бодрствующего в текущей области видимости (из-за пункт № 1 выше) и потому value_on_root доступна через текущую область (из-за пункт № 2 выше), $digest делает именно то, что он должен:

обрабатывает все наблюдатели в текущей области и ее детей

Если мы ч ad a value_on_root наблюдатель за пределами текущей области или если область вашего контроллера имеет isolate scope, обновления свойств на $rootScope не будут отображаться в DOM.

Я немного изменил ваш код in this example, чтобы доказать свою точку зрения. Я неявно разместил наблюдателя value_on_root вне области действия контроллера, добавив {{value_on_root}} к окружающему HTML. Обратите внимание, что в этом примере внешний value_on_root не обновляется при загрузке изображения.

Если вы изменили $digest на $apply в my example, то внешний value_on_root обновится.

Смежные вопросы