यह एक दो में ObjectProxy
जायके का उपयोग कर, अपनी आवश्यकताओं पर निर्भर करता है संभव है। दोनों दृष्टिकोण केवल पर्यवेक्षक कहलाते हैं और कितने बार Ember.keys
पर भरोसा करते हैं।
दोनों समाधानों के लिए HTML समान है।
एचटीएमएल
<script type="text/x-handlebars" data-template-name="app">
Name: {{App.MyObject.firstname}} {{App.MyObject.lastname}}
<ul>
{{#each App.List}}
<li>{{this}}</li>
{{/each}}
</ul>
</script>
समाधान 1
JsFiddle: http://jsfiddle.net/2zxSq/
जावास्क्रिप्ट
App = Em.Application.create();
App.List = [];
App.MyObject = Em.ObjectProxy.create({
// Your Original object, must be defined before 'init' is called, however.
content: Em.Object.create({
firstname: 'first',
lastname: 'last'
}),
// These following two functions can be abstracted out to a Mixin
init: function() {
var self = this;
Em.keys(this.get('content')).forEach(function (k) {
Em.addObserver(self.get('content'), k, self, 'personChanged')
});
},
// Manually removing the observers is necessary.
willDestroy: function() {
var self = this;
Em.keys(this.get('content')).forEach(function (k) {
Em.removeObserver(self.get('content'), k, self, 'personChanged');
});
},
// The counter is for illustrative purpose only
counter: 0,
// This is the function which is called.
personChanged: function() {
// This function MUST be idempotent.
this.incrementProperty('counter');
App.List.pushObject(this.get('counter'));
console.log('person changed');
}
});
App.ApplicationView = Em.View.extend({
templateName: 'app'
});
// Test driving the implementation.
App.MyObject.set('firstname', 'second');
App.MyObject.set('lastname', 'last-but-one');
App.MyObject.setProperties({
'firstname': 'third',
'lastname' : 'last-but-two'
});
MyObject
initialising, वहीं सभी गुण जो पहले से हीcontent
वस्तु पर मौजूद मनाया जाता है, और समारोह personChanged
हर बार संपत्ति से कोई भी परिवर्तन कहा जाता है। हालांकि, चूंकि पर्यवेक्षकों को उत्सुकता से निकाल दिया जाता है [1], फ़ंक्शन personChanged
idempotent होना चाहिए, उदाहरण में फ़ंक्शन नहीं है। अगला समाधान पर्यवेक्षक आलसी बनाकर इसे ठीक करता है।
समाधान 2
JsFiddle: http://jsfiddle.net/2zxSq/1/
जावास्क्रिप्ट
App.MyObject = Em.ObjectProxy.create({
content: Em.Object.create({
firstname: 'first',
lastname: 'last'
}),
init: function() {
var self = this;
Em.keys(this.get('content')).forEach(function (k) {
Em.addObserver(self, k, self, 'personChanged')
});
},
willDestroy: function() {
var self = this;
Em.keys(this.get('content')).forEach(function (k) {
Em.removeObserver(self, k, self, 'personChanged');
});
},
// Changes from here
counter: 0,
_personChanged: function() {
this.incrementProperty('counter');
App.List.pushObject(this.get('counter'));
console.log('person changed');
},
// The Actual function is called via Em.run.once
personChanged: function() {
Em.run.once(this, '_personChanged');
}
});
यहाँ केवल परिवर्तन है कि वास्तविक पर्यवेक्षक समारोह अब केवल the end of the Ember Run loop पर जो हो सकता है कहा जाता है, है वह व्यवहार बनें जिसे आप ढूंढ रहे हैं।
अन्य नोट
ये समाधान के बजाय वस्तु पर ही पर्यवेक्षकों को परिभाषित करने के लिए या एक explicit list of properties to observe (जैसे init
, willDestroy
, आदि के रूप गुणों) पर नकली पर्यवेक्षकों की स्थापना से बचने के लिए की ObjectProxy
का उपयोग करें।
यह समाधान प्रॉक्सी पर setUnknownProperty
को ओवरराइड करके गतिशील गुणों को देखने के लिए बढ़ाया जा सकता है ताकि हर बार एक कुंजी को content
में जोड़ा जा सके। willDestroy
वही रहेगा।
संदर्भ
[1] इस जल्द ही asyn पर्यवेक्षकों के लिए बदल दिया धन्यवाद हो सकता है
इस होगा http://stackoverflow.com/questions/11623645/ember-js-observer-for- सभी मूल्य/11679850 # 11679850 आपके लिए काम करते हैं? –