2012-12-29 47 views
9

Tôi muốn quan sát tất cả các thay đổi trên một thuộc tính đối tượng.
Trong ví dụ sau, tôi muốn được thông báo bởi người quan sát được đổi tên nếu tên hoặc họ được thay đổi.
NHƯNG Tôi muốn có một cái gì đó chung áp dụng trên tất cả các thuộc tính đối tượng (sử dụng Ember.keys() ??) Làm thế nào để thay thế 'firstname', 'lastname' với một cái gì đó chung chung hơn?Ember.js: Quan sát tất cả các thuộc tính đối tượng

Trong ví dụ của tôi:

personChanged được gọi khi firstname hay lastname được thay đổi:

App.MyObject: Ember.Object.create({ 
    firstname: 'first', 
    lastname: 'last', 
    personChanged: Ember.observer(function() { 
      console.log("person changed"); 
    }, 'firstname', 'lastname') 
}) 
+0

sẽ này http://stackoverflow.com/questions/11623645/ember-js-observer-for- tất cả giá trị/11679850 # 11679850 phù hợp với bạn? –

Trả lời

2

gì bạn đã có như vậy là hợp sử dụng quan sát nội tuyến, nhưng bạn chỉ có một số lỗi cú pháp. Tuy nhiên nó thậm chí còn đơn giản hơn để làm với từ khóa observes. Vì vậy, tôi đã chỉnh sửa ví dụ của bạn một chút dưới đây.

App.MyObject: Ember.Object.create({ 
    firstname: 'first', 
    lastname: 'last', 
    personChanged: function() { 
     //firstname or lastname changed 
    }.observes('firstname','lastname') 
}); 

Lưu ý: tôi đặt dấu ngoặc kép quanh các thuộc tính

Nguồn:http://emberjs.com/guides/object-model/observers/

+1

Tx nhưng câu hỏi của tôi là lấy một giải pháp chung để quan sát tất cả các thuộc tính đối tượng (không viết danh sách thuộc tính trong phương thức quan sát) – fvisticot

+0

Xin lỗi nhưng không có cách nào để làm điều đó trừ khi bạn lưu trữ tất cả các thuộc tính của bạn trong một mảng hoặc một đối tượng và quan sát điều đó và sau đó thực hiện một số phép tính thủ công để truy xuất các giá trị. – Akash

8

Điều này có thể sử dụng một ObjectProxy trong hai hương vị, tùy thuộc vào yêu cầu của bạn. Cả hai cách tiếp cận này chỉ khác nhau về thời gian và người quan sát gọi bao nhiêu lần và cả hai đều dựa vào số Ember.keys.

HTML cho cả hai giải pháp đều giống nhau.

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> 

Giải pháp 1

JsFiddle: http://jsfiddle.net/2zxSq/

Javascript

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' 
}); 

Trong khi initialising MyObject, tất cả tài sản mà đã tồn tại trên các đối tượng content được quan sát, và các chức năng personChanged được gọi là mỗi lần bất kỳ thay đổi tài sản. Tuy nhiên, kể từ khi các nhà quan sát bị sa thải háo hức [1], chức năng personChanged phải là idempotent, mà chức năng đó không phải là. Các giải pháp tiếp theo sửa lỗi này bằng cách làm cho người quan sát lười biếng.

Giải pháp 2

JsFiddle: http://jsfiddle.net/2zxSq/1/

Javascript

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'); 
    } 
}); 

Sự thay đổi duy nhất ở đây là các chức năng quan sát thực tế hiện nay được gọi là chỉ the end of the Ember Run loop, mà có thể là hành vi bạn đang tìm kiếm.

ghi chú khác

Những giải pháp này sử dụng ObjectProxy thay vì định quan sát trên đối tượng riêng của mình để tránh thiết lập các quan sát viên giả mạo (trên thuộc tính như init, willDestroy, vv) hoặc một explicit list of properties to observe.

Giải pháp này có thể được mở rộng để bắt đầu quan sát các thuộc tính động bằng cách ghi đè setUnknownProperty trên proxy để thêm người quan sát mỗi lần khóa được thêm vào content. willDestroy sẽ vẫn giữ nguyên.

Reference

[1] Điều này có thể thay đổi nhanh chóng nhờ vào quan sát asyn

Các vấn đề liên quan