2013-09-04 11 views
17
Todos.TodoController = Ember.ObjectController.extend({ 
    isCompleted: function(key, value){ 
    var model = this.get('model'); 

    if (value === undefined) { 
     // property being used as a getter 
     return model.get('isCompleted'); 
    } else { 
     // property being used as a setter 
     model.set('isCompleted', value); 
     model.save(); 
     return value; 
    } 
    }.property('model.isCompleted') 
}); 

Tôi đang làm việc thông qua hướng dẫn ToDo cho Ember.js và dường như tôi không hiểu bộ điều khiển này hoạt động như thế nào. Giá trị .property() có nghĩa là gì? Và làm thế nào đến khi tôi loại bỏ 'giá trị trả lại'; dòng chức năng vẫn giữ nguyên. Nếu ai đó có thể giải thích chính xác những gì đang xảy ra ở đây sẽ thật tuyệt vời..property() làm gì? trong hàm() {}. property()

Liên kết với các hướng dẫn: http://emberjs.com/guides/getting-started/marking-a-model-as-complete-incomplete/

+2

http://emberjs.com/guides/object-model/computed-properties/ –

+1

@RUJordan tôi vẫn không hiểu tại sao bạn cần .property() trong mã này 'fullName: function() { trả về this.get ('firstName') + '' + this.get ('lastName'); } .property ('firstName', 'lastName') 'nó vẫn có vẻ dư thừa để có cả một trở lại và một .property() – Wilfred

+0

Cũng trong đoạn mã này' App.SongsController = Ember.ArrayController.extend ({ longSongCount : function() { var longSongs = this.filter (hàm (bài hát) { trả về bài hát.get ('duration')> 30; }); trả về longSongs.get ('length'); } .property ('@ each.duration') }); 'Bạn đã trả về độ dài của longSongs vậy tại sao bạn cần .property ('@ each.duration')? – Wilfred

Trả lời

18

Trong javascript cách duy nhất để làm một số xử lý khi nhận được hoặc thiết lập một tài sản đang sử dụng Object.defineProperty:

Object.defineProperty(person, "b", { 
    get : function() { 
    return person.firstName + ' ' + person.surname; 
    }, 
    set : function(newValue) { 
    var names = newValue.split(' '); 
    person.firsname = names[0]; 
    person.surname = names[1]; 
    }, 
    enumerable : true, 
    configurable : true 
}); 

Nhưng điều này có một số nhược điểm:

  • Không phải là trình duyệt chéo
  • Không có ràng buộc, nói cách khác, nếu firstname hoặc surname thay đổi, thuộc tính phụ thuộc fullname không thay đổi.
  • Calling person.name khi person là undefined, làm cho một lỗi được ném
  • là không thể thực hiện để kích hoạt các nhà quan sát, không có không có mã bổ sung và nhận thức được những hệ thống phân cấp depency: firstname phụ thuộc từ fullname, và nó có thể phụ thuộc của người khác tài sản arghhh!

Do Ember này có khái niệm "thuộc tính", được gọi là computed property.

Nó có thể được khai báo trong 2 cách sau:

foo: Ember.computed(function({ 
    ... 
}).property(dependent keys); 

hoặc khi sử dụng (mặc định) Ember.ENV.EXTEND_PROTOTYPES = true:

foo: function() { 
    ... 
}.property(dependent keys); 

Các property(dependent keys), là cần thiết vì nó nói đến Ember gì là properies rằng khi thay đổi, sẽ làm cho tài sản được cập nhật.

fullname: function(key, value) { 
    // setter 
    if (value !== undefined) { 
    var names = value.split(' '); 
    this.set('firstname', names[0]); 
    this.set('surname', names[1]); 
    } 
    // always return the complete result, so nexts calls to this.get('fullname') will return the cached value 
    return this.get('firstname') + ' ' + this.get('surname'); 
}.property('firstname', 'surname') 

Sử dụng này, bạn có lợi thế của:

  • khi thay đổi firstname hay surname đến một giá trị mới, fullname được thay đổi.
  • Các beforeObserves được kích hoạt trước khi thay đổi giá trị, và observes được kích hoạt sau khi thay đổi giá trị.
  • Bất kỳ mẫu nào tham chiếu đến một số thuộc tính được cập nhật
  • Sau đó, một cuộc gọi đến person.get ('firstname'), sẽ trả lại giá trị được lưu trong bộ nhớ cache, lưu chế biến. Bạn có thể tắt tính năng này bằng cách sử dụng .property(..).volatile()
  • Tránh lỗi không xác định hoặc không xác định, khi truy cập các đối tượng rỗng như: controller.get('person.dog.name') trả về undefined, nếu người hoặc chó không xác định.

Tôi hy vọng nó giúp

+0

Ok cảm ơn bạn! Tôi bắt đầu hiểu điều này tốt hơn. Vì vậy, làm thế nào đến trong ví dụ trong câu hỏi ban đầu là khóa phụ thuộc ''model.isCompleted'' và không chỉ'' isCompleted''? – Wilfred

+0

Sự nhầm lẫn là vì tên gần giống nhau, nhưng hãy tham khảo hai thuộc tính khác nhau. 'isCompleted' phụ thuộc vào' model.isCompleted' và nếu chúng ta sử dụng 'isCompleted: function() {...} .property ('isCompleted')', sẽ tham chiếu đến thuộc tính. –

5

.property() đánh dấu chức năng như một tài sản tính để nó có thể được sử dụng trong các mẫu, ví dụ, theo một cách nhất quán. Đây có phải là tài sản JavaScript foo không? Hoặc là một hàm foo()? Thuộc tính tính toán giải quyết vấn đề này trên tất cả các nền tảng.

Các trường và đường dẫn được truyền dưới dạng đối số là các khóa phụ thuộc phụ thuộc. Tất cả các thuộc tính được tính toán trong Ember được lưu trữ theo mặc định. Để biết khi nào một thuộc tính tính toán cần phải được tính toán lại, Ember cần phải biết thuộc tính và đường dẫn nào phụ thuộc vào nó. Trong ví dụ của hướng dẫn, thuộc tính được tính fullName phụ thuộc vào firstNamelastName; Ember cần phải biết rằng nó có thể tính toán lại fullName khi một trong những thay đổi đó. (Lưu ý: Bạn có thể tắt bộ nhớ đệm bằng cách sử dụng .property().volatile().)

Vui lòng đọc hướng dẫn. Tất cả những điều này được ghi lại ở đó.

+0

Vì vậy, trong mẫu có '

  • {{input type =" checkbox "checked = isCompleted class =" toggle "}}
  • 'và lý do duy nhất hoạt động này là vì isCompleted có một .property() ở cuối? – Wilfred

    +0

    Một phần, có. Và các khóa phụ thuộc là những gì cho phép Ember cập nhật nó. –

    +0

    phần thuộc tính được tính toán của 2.16.0 không chứa bất kỳ thứ gì trên '.property()' mặc dù https://guides.emberjs.com/v2.16.0/object-model/computed-properties/ –