2014-12-11 1 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이 새로운 값을 반환하면 이러한 바인딩을 시도하면 브라우저 탭이 손상됩니다 (크롬 39이므로 기본 객체 관찰의 결과라고 생각합니다). 예를 들어

:

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

는 이유는 무엇입니까? 이 패턴을 시도하면 또 무엇을 염려해야합니까? 이 문제가 더 일반적으로 당신이 생각하는 것보다 올 수 있다고,

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

주, BTW :

는 여기에 문제의 다른 순열보다 완성 개요입니다. 하나는 게터에서 개체를 반환하는 경우 : 실수로 각 액세스에 새로 만들

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

귀하의 폴리머가 폐액 처리를하지 못했다고 생각합니다.')' –

+0

고맙습니다, 스털링. 수정 됨. –

+1

'changingValueChanged' 리스너 내부에서'this.internalData.changingValue'에 대한 액세스가 변경 이벤트의 무한 루프를 야기하는 새로운 값을 생성하게한다고 생각합니다. 데이터 액세스 및 데이터 변경은 항상 일치하므로 데이터를 변경하면 데이터에 액세스 할 때 무한 루프가 발생합니다. 'changingValueChanged' 함수가'changingValue'에 접근하지 않으면, 무한 루프가없는 것 같습니다. 그러나 콘솔에서'changingValue'에 액세스하면 변경 리스너가 실행되지 않기 때문에 전체 스토리가 아닌 것 같습니다. – apsillers

답변

2

아니 완전한 답변을 예컨대을 쉽게,하지만 그는 시작이다 :

은 고려 때 changingValueChanged 실행됩니다. changingValue 변경 될 때마다 실행됩니다.

changingValue이 변경 될 때를 고려하십시오. 액세스 할 때마다 변경됩니다. 충돌을 이해하기

마지막 조각은 changingValueChangedchangingValue에 액세스하는 것입니다 :

this.observedChangingValue = this.internalData.changingValue; 

그 과제에 대한 값에 액세스 값을 변경 영원히 반복하는, 다시 실행 리스너를 야기 할것이다.

각 액세스마다 항상이 다를 수 있다는 것을 의미심장하게 관찰 할 수없는 것으로 보입니다. 변수가 변경되었다는 사실을 알게 된 후 해당 변수의 값을 캡처하려는 것은 의미가 없습니다. 변수는 기능적으로 생성자입니다. 변수에 새로운 값을 줄 수 있기 때문에 값을 방금 가져온 변수를 요청할 수 없습니다. 반면에 은 값에 액세스하는 행위 이외의 다른 것에 기초하여 값을 변경하기 때문에 단순히 가끔씩 변경되는 게터 기반 변수를 관찰 할 수 있습니다.

변수와 관련되지 않은 항목 (예 : console.log("hello"))을 수행하도록 수신기를 변경하고 this.internalData.changingValue에 액세스하지 않으면 무한 루프가 발생하지 않습니다. 새로운 관측 값은 변경 리스너에 제공된 첫 번째 인수에 있으므로 값을 안전하게 얻을 수 있습니다. 그러나 Polymer에 의해 페이지에 최종적으로 표시되는 값은 아닙니다. Polymer는 DOM에 값을 넣으려는 또 다른 액세스를 수행합니다.

그러나, 변경 청취자가 콘솔에 externalData.changingValue에 액세스 할 때 실행되는 것처럼하지 않습니다,하지만, 객체의 속성을 보여주는, externalData에 액세스 할 때 그것은 실행을 수행합니다.

내가 무엇을하는지 모르기 때문에 compute 속성이 페이지를 왜 망칩니다.

+0

포괄적입니다. 자세한 답변을 주셔서 감사합니다. 생성기 인 getter도 계산 된 값을 가진 무한 호출 사이클에 또한 들어갈 것입니다. 템플릿에서 단순히 사용하면 getter에 대한 새 액세스가 트리거되기 때문입니다. 예제에서 {{computedChangingValue}}의 사용을 제거하면 브라우저 탭을 손상시키지 않고 실제로 실행됩니다. 참고로,이 패턴에서 생각하는 것보다 더 일반적으로 발생할 수 있습니다. getter에서 Object를 반환하면 실수로 각 액세스에 대해 새 객체를 만들 수 있습니다. 이에 대해 메모를 추가하겠습니다. –