AngularJS: Разница между методами $ наблюдать и $ смотреть

Если вы хотите определить разрешение экрана, вы можете проверить плагин res . Это позволяет вам сделать следующее:

var res = require('res')
res.dppx() // 1
res.dpi() // 96
res.dpcm() // 37.79527559055118

Вот некоторые отличные выходы разрешения от Райана Ван Эттен, автора плагина:

  • 2 единицы набора существуют и различаются в фиксированном масштабе: единицы устройства и единицы CSS.
  • Разрешение рассчитывается как количество точек, которые могут поместиться вдоль определенной длины CSS.
  • Преобразование единиц : 1⁢in = 2,54⁢cm = 96⁢px = 72⁢pt
  • CSS имеет относительную и абсолютную длину. При нормальном масштабировании: 1⁢em = 16⁢px
  • dppx эквивалентно соотношению пикселей к устройству.
  • devicePixelRatio-определение отличается платформой.
  • Запросы к мультимедиа может мигать с минимальным разрешением. Использовать с осторожностью относительно скорости.

Вот исходный код для res, на сегодняшний день:

!function(root, name, make) {
  if (typeof module != 'undefined' && module.exports) module.exports = make()
  else root[name] = make()
}(this, 'res', function() {

  var one = {dpi: 96, dpcm: 96 / 2.54}

  function ie() {
    return Math.sqrt(screen.deviceXDPI * screen.deviceYDPI) / one.dpi
  }

  function dppx() {
    // devicePixelRatio: Webkit (Chrome/Android/Safari), Opera (Presto 2.8+), FF 18+
    return typeof window == 'undefined' ? 0 : +window.devicePixelRatio || ie() || 0
  }

  function dpcm() {
    return dppx() * one.dpcm
  }

  function dpi() {
    return dppx() * one.dpi
  }

  return {'dppx': dppx, 'dpi': dpi, 'dpcm': dpcm}
});

375
задан Adam Bubela 30 January 2017 в 12:45
поделиться

4 ответа

$ наблюдаем () - это метод объекта Атрибуты , и поэтому его можно использовать только для наблюдения / наблюдения за изменением значения атрибут DOM. Он используется / вызывается только внутри директив. Используйте $ наблюдаем, когда вам нужно наблюдать / смотреть атрибут DOM, который содержит интерполяцию (т. Е. {{}}).
Например, attr1="Name: {{name}}", затем в директиве: attrs.$observe('attr1', ...).
(Если вы попытаетесь scope.$watch(attrs.attr1, ...), это не сработает из-за {{}} s - вы получите undefined.) Используйте $ watch для всего остального.

$ watch () сложнее. Он может наблюдать / наблюдать «выражение», где выражение может быть либо функцией, либо строкой. Если выражение является строкой, оно превращается в функцию $ parse 'd (т.е. оценивается как угловое выражение ) в функцию. (Именно эта функция вызывается каждый цикл дайджеста.) Строковое выражение не может содержать {{}}. $ watch - это метод объекта Scope , поэтому его можно использовать / вызывать везде, где у вас есть доступ к объекту области видимости, поэтому в

  • контроллер - любой контроллер - - созданная с помощью ng-view, ng-controller или контроллера директивы
  • связующая функция в директиве, поскольку она также имеет доступ к области действия

, поскольку строки оцениваемый как угловое выражение, $ watch часто используется, когда вы хотите наблюдать / наблюдать свойство model / scope. Например, attr1="myModel.some_prop", затем в функции контроллера или связи: scope.$watch('myModel.some_prop', ...) или scope.$watch(attrs.attr1, ...) (или scope.$watch(attrs['attr1'], ...)).
(Если вы попытаетесь attrs.$observe('attr1'), вы получите строку myModel.some_prop, что, вероятно, не то, что вы хотите.)

Как обсуждалось в комментариях к ответу @ PrimosK, все $ наблюдают и $ watches проверяются каждый цикл дайджеста .

Директивы с изолированными областями более сложны. Если используется синтаксис '@', вы можете $ наблюдаем или $ watch атрибут DOM, который содержит интерполяцию (то есть {{}}). (Причина, по которой он работает с $ watch, заключается в том, что синтаксис '@' выполняет для нас интерполяцию , поэтому $ watch видит строку без {{}}.) Чтобы упростить запоминание того, какой используйте, когда, я предлагаю использовать $ наблюдаем также для этого случая.

Чтобы помочь проверить все это, я написал Plunker , который определяет две директивы. Один (d1) не создает новую область, другой (d2) создает изолированную область. Каждая директива имеет одинаковые шесть атрибутов. Каждый атрибут - и $ наблюдаем, и $ наблюдаем.

<div d1 attr1="{{prop1}}-test" attr2="prop2" attr3="33" attr4="'a_string'"
        attr5="a_string" attr6="{{1+aNumber}}"></div>

Посмотрите журнал консоли, чтобы увидеть различия между $ наблюдаем и $ наблюдаем в функции связывания. Затем нажмите на ссылку и посмотрите, какие $ наблюдатели и $ watches запускаются изменениями свойств, сделанными обработчиком кликов.

Обратите внимание, что при запуске функции ссылки все атрибуты, содержащие {{}}, еще не оцениваются (поэтому, если вы попытаетесь проверить атрибуты, вы получите undefined). Единственный способ увидеть интерполированные значения - это использовать $ наблюдаю (или $ наблюдаем, если используем изолированную область с '@'). Следовательно, получение значений этих атрибутов является асинхронной операцией . (И именно поэтому нам нужны функции $ наблюдений и $ наблюдений.)

Иногда вам не нужны $ наблюдать или $ смотреть. Например, если ваш атрибут содержит число или логическое значение (не строку), просто оцените его один раз: attr1="22", а затем, скажем, в вашей функции связывания: var count = scope.$eval(attrs.attr1). Если это просто константная строка & ndash; attr1="my string" & ndash; затем просто используйте attrs.attr1 в вашей директиве (нет необходимости в $ eval ()).

См. Также пост группы Google Войты о выражениях $ watch.

606
ответ дан Red15 30 January 2017 в 12:45
поделиться

Я думаю, это довольно очевидно:

  • $ Наблюдение используется в функции связывания директив.
  • $ watch используется в области видимости для отслеживания любых изменений его значений.

Имейте в виду : обе функции имеют два аргумента,

$observe/$watch(value : string, callback : function);
  • значение : всегда является строковой ссылкой на отслеживаемый элемент (имя переменной области действия или имя атрибута директивы, который необходимо просмотреть)
  • обратный вызов : функция, которая должна быть выполнена в форме function (oldValue, newValue)

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

1
ответ дан vdegenne 30 January 2017 в 12:45
поделиться

Если я правильно понимаю ваш вопрос, вы спрашиваете, в чем разница, если вы регистрируете обратный вызов слушателя с помощью $watch или если вы делаете это с помощью $observe.

Обратный вызов, зарегистрированный с $watch, запускается при выполнении $digest.

Обратный вызов, зарегистрированный с помощью $observe, вызывается при изменении значения атрибутов, которые содержат интерполяцию (например, attr="{{notJetInterpolated}}").


Внутри директивы вы можете использовать оба из них очень похожим образом:

    attrs.$observe('attrYouWatch', function() {
         // body
    });

или

    scope.$watch(attrs['attrYouWatch'], function() {
         // body
    });
23
ответ дан Abhay Dixit 30 January 2017 в 12:45
поделиться

Почему $ visible отличается от $ watch?

watchExpression оценивается и сравнивается с предыдущим значением в каждом цикле digest (), если в значении watchExpression есть изменение, вызывается функция watch.

$ Наблюдение является специфическим для отслеживания интерполированных значений. Если значение атрибута директивы интерполировано, например, dir-attr="{{ scopeVar }}", функция наблюдения будет вызываться только тогда, когда установлено интерполированное значение (и, следовательно, когда $ digest уже определил, что обновления должны быть выполнены). По сути, уже есть наблюдатель для интерполяции, и функция $ наблюдайте за этим.

См. $ Наблюдать & amp; $ set в compile.js

0
ответ дан Niko 30 January 2017 в 12:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: