2012-04-22 47 views
24

Tôi không thực sự có được chức năng reopenClass của ember.js. Tôi nghĩ rằng nó thêm mã thêm vào nguyên mẫu của Object, vì vậy tất cả các trường hợp của đối tượng đó sẽ nhận được các chức năng được thêm vào một cách không tĩnh. Nó không làm điều này tuy nhiên. Có vẻ như nó chỉ thêm mã có thể được thực thi tĩnh. Ví dụ. Tôi có mã này:Ember.js reopenClass hoạt động như thế nào?

Logger = Ember.Object.extend({ 
    log: function(thing) { 
    console.log(thing + ' wassup'); 
    } 
}); 

var logger = Logger.create(); 
logger.log("1, yo") 

logger.reopen({ 
    log: function(name) { 
     console.log(name + 'ghurt') 
    } 
}); 
logger.log("2, yo") 

Logger.reopenClass({ 
    log: function(name) { 
     console.log(name + 'fresh') 
    } 
}); 
logger.log("3, yo") 
Logger.log("4, yo") 

Nó ra này:

1, yo wassup 
2, yoghurt 
3, yoghurt 
4, yofresh 

gì tôi mong đợi là thế này:

1, yo wassup 
2, yoghurt 
3, yofresh 
4, undefined (I think) 

Vì vậy, câu hỏi của tôi là: không reopenClass làm gì và khi nào tôi sử dụng nó?

Trả lời

44

Nói chung, reopen thêm phương pháp và tài sản cho trường trong khi reopenClass thêm phương pháp và tài sản cho lớp.

Các thử nghiệm tương ứng là ember-runtime/tests/system/object/reopen_test.jspackages/ember-runtime/tests/system/object/reopenClass_test.js.

Tôi đã cập nhật mã của bạn và thêm một số ý kiến, xem http://jsfiddle.net/pangratz666/yWKBF/:

Logger = Ember.Object.extend({ 
    log: function(thing) { 
     console.log(thing + ' wassup'); 
    } 
}); 

var logger1 = Logger.create(); 
var logger2 = Logger.create(); 

// instances of Logger have a 'wassup' method 
try { Logger.log("1, yo"); } catch (e) {} // Object (subclass of Ember.Object) has no method 'log' 
logger1.log("1, yo"); // 1, yo wassup 
logger2.log("1, yo"); // 1, yo wassup 

console.log('----'); 

// overwrite log of concrete logger instance logger1 
logger1.reopen({ 
    log: function(name) { 
     console.log(name + ' ghurt'); 
    } 
}); 

try { Logger.log("1, yo"); } catch (e) {} // Object (subclass of Ember.Object) has no method 'log' 
logger1.log("2, yo"); // 2, yo ghurt 
logger2.log("2, yo"); // 2, yo wassup 

console.log('----'); 

// classes of Logger have a 'fresh' method 
Logger.reopenClass({ 
    log: function(name) { 
     console.log(name + ' fresh'); 
    } 
}); 

Logger.log("3, yo"); // 3, yo fresh 
logger1.log("3, yo"); // 3, yo ghurt 
logger2.log("3, yo"); // 3, yo wassup 

console.log('----'); 

// new* instances of Logger have from now on a 'dawg' method 
// * this will likely change in the future so already existing instances will reopened too 
Logger.reopen({ 
    log: function(name) { 
     console.log(name + ' dawg'); 
    } 
}); 

Logger.log("4, yo"); // 4, yo fresh 
logger1.log("4, yo"); // 4, yo ghurt 
logger2.log("4, yo"); // 4, yo wassup 
Logger.create().log("4, yo"); // 4, yo dawg 

console.log('----'); 

+9

Ok, vì vậy Nếu tôi nhận được r này ight logger.reopen() chỉ thêm mã vào cá thể logger, Logger.reopen() thêm mã cho mỗi cá thể mới sẽ được tạo (các cá thể hiện tại sẽ không được thay đổi) và Logger.reopenClass() thêm mã tĩnh lớp Logger (nó không thể được gọi từ các cá thể, chỉ là tĩnh). Chính xác? – koenpeters

+0

Đúng, đúng vậy. – pangratz

+2

Ok. Cảm ơn vì đã đổ ánh sáng. Tôi đã có một thời gian khó hiểu điều này (như trong: Tôi đã không nhận được nó) từ tài liệu tại http://emberjs.com/documentation/. – koenpeters

0

reopen thay đổi mẫu và do đó thay đổi trường của một lớp

reopenClass thay đổi các nhà xây dựng chính nó và do đó thay đổi lớp bằng cách tạo các thuộc tính và chức năng tĩnhchỉ khả dụng trên lớp nhưng không có trên bất kỳ trường hợp nào của lớp.

Lưu ý rằng những thay đổi được giới thiệu bởi reopen chỉ có hiệu lực sau khi gọi .create()

ví dụ Mã dựa trên doc:

http://emberjs.com/api/classes/Ember.Application.html#method_reopen

MyObject = Ember.Object.extend({ 
    name: 'an object' 
}); 

o = MyObject.create(); 
o.get('name'); // 'an object' 

MyObject.reopen({ 
    say: function(msg){ 
    console.log(msg); 
    } 
}) 

try{ 
    o.say("hey"); 
} catch(e) { 
    console.log(e); // o.say is not a function (...yet) 
} 
o2 = MyObject.create(); 
o2.say("hello"); // logs "hello" 

o.say("goodbye"); // logs "goodbye" 

http://emberjs.com/api/classes/Ember.Application.html#method_reopenClass

MyObject = Ember.Object.extend({ 
    name: 'an object' 
}); 

MyObject.reopenClass({ 
    canBuild: false 
}); 

MyObject.canBuild; // false 
o = MyObject.create(); 
o.canBuild; // undefined 
Các vấn đề liên quan