2014-12-11 3 views
1

Я использую PolymerJS.Каковы нюансы наблюдения «собственности», которая фактически получена геттером?

Похоже на наблюдение за свойством, полученным с помощью getter работ.

Например, следующий код, кажется, работает:

<div>Direct binding to property: {{internalData.value}}</div> 
<div>Binding to computed value: {{computedValue}}</div> 
<div>Binding to observed value: {{observedValue}}</div> 

<script> 
    var externalData = { 
    get value() { 
     return 'static value'; 
    } 
    }; 

    Polymer('my-element', { 
    internalData: externalData, 
    computed: { 
     computedValue: 'internalData.value' 
    }, 
    observe: { 
     'internalData.value': 'valueChanged' 
    }, 
    valueChanged: function() { 
     this.observedValue = this.internalData.value; 
    } 
    }); 
</script> 

Однако, что если мой getter определяет что-то более сложное? Я обнаружил, что если getter возвращает новое значение при каждом вызове, то попытка такого привязки приведет к сбою моей вкладки в браузере (это Chrome 39, поэтому я считаю, что это результат наблюдения за собственным объектом).

Например:

var externalData = {  
    get changingValue() { 
    return Math.random(); 
    } 
} 

Почему это? Чего еще я должен беспокоиться, если я попытаюсь использовать этот шаблон?

Вот более-полный изношенном различных перестановок задачи:

http://jsbin.com/reder/28/edit?html,output

Заметим, кстати, что этот вопрос может придумать чаще, чем вы думаете. Если один возвращает объект из добытчика, это легко случайно создать новую на каждый доступ, например .:

var externalData = {  
    get changingValue() { 
    return { foo: 'bar' }; 
    } 
} 
+0

Я думаю, что у вашего Полимера отсутствует закрытие ')' –

+0

Спасибо, Стерлинг. Измененный. –

+1

Я бы предположил, что ваш доступ к 'this.internalData.changingValue' внутри слушателя' changeValueChanged' вызывает генерирование нового значения, что вызывает бесконечный цикл изменений. Доступ к данным и изменение данных всегда совпадают, поэтому, если изменение данных приведет к доступу к данным, будет бесконечный цикл. Если функция 'changeValueChanged' не имеет доступа к' changeValue', кажется, что нет бесконечного цикла. Однако это не похоже на всю историю, потому что доступ к 'changeValue' с консоли не запускает прослушиватель изменений. – apsillers

ответ

2

Не полный ответ, но он старт:

Рассмотрит, когда changingValueChanged работает. Он запускается каждый раз, когда изменяется changingValue.

Рассмотрите, когда changingValue изменений. Он изменяется каждый раз, когда к нему обращаются.

Заключительная часть, чтобы понять крах, что changingValueChanged обращается к changingValue:

this.observedChangingValue = this.internalData.changingValue; 

При обращении значения для этого задания, вы измените значение и АНОМАЛЬНЫЙ слушатель запустить снова, который повторяет навсегда.

Похоже, что вы не можете осмысленно наблюдать за значением, которое будет всегда быть различным при каждом доступе. Не упоминайте, что попытка захватить значение этой переменной после того, как вы знаете, что она изменилась, не имеет смысла: переменная функционально является генератором. Вы не можете спросить переменную, какое значение она имела, потому что она может только дать вам новые значения. С другой стороны, вы можете использовать переменную, основанную на геттере, которая иногда изменяется, поскольку она меняет свое значение на основе чего-то другого, кроме действия доступа к значению.

Если вы изменили свой слушатель, чтобы сделать что-то, не связанное с переменной (например, просто сделать console.log("hello")) и никогда не обращаться к this.internalData.changingValue, нет бесконечного цикла. Обратите внимание, что новое наблюдаемое значение находится в первом аргументе, предоставленном слушателю изменений, поэтому вы можете безопасно получить значение таким образом. Однако это не значение, которое в конечном итоге отображается на странице компанией Polymer; похоже, что у Polymer есть еще один доступ, чтобы прочитать значение, чтобы поместить его в DOM.

Однако, обратите внимание, что изменение слушатель не отображается для запуска при доступе externalData.changingValue в консоли, но это делает запуск при доступе к externalData, который показывает все свойства объекта.

Я не могу говорить, почему собственность compute разбивает страницу, потому что я не знаю, что это делает.

+0

Близко к всеобъемлющему. Большое спасибо за подробный ответ. Имеет смысл, что геттер, который является генератором, также попадает в бесконечный цикл вызова с вычисленным значением, так как, как вы говорите, просто его использование в шаблоне вызовет новый доступ к получателю. Если я удалю использование {{computedChangingValue}} в моем примере, он действительно запускается без сбоев на вкладке браузера. Обратите внимание, кстати, что это может возникнуть чаще в этом шаблоне, чем вы думаете. Если вы возвращаете объект из получателя, легко случайно создать новый для каждого доступа. Я добавлю примечание об этом. –

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