2012-04-22 2 views
24

Я действительно не получаю функцию ember.js 'reopenClass. Я думал, что он добавил дополнительный код к прототипу Object, поэтому все экземпляры этого объекта получат функциональность, которая была добавлена ​​нестационарным способом. Однако это не делает. Похоже, что он только добавляет код, который можно статически выполнять. Например. У меня есть этот код:Ember.js как работает reopenClass?

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") 

Он выводит это:

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

Что я ожидал, был такой:

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

Так что мой вопрос: Что reopenClass делать и когда я могу использовать Это?

ответ

44

В общем, reopen добавляет методы и свойства для случаев, тогда какreopenClass добавляет методы и свойства для классов.

Соответствующие испытания: ember-runtime/tests/system/object/reopen_test.js и packages/ember-runtime/tests/system/object/reopenClass_test.js.

Я обновил свой код и добавил некоторые комментарии, см 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, так Если я получу это r ight logger.reopen() только добавляет код в экземпляр журнала, Logger.reopen() добавляет код для каждого нового экземпляра, который будет создан (существующие экземпляры не будут изменены), а Logger.reopenClass() добавляет код, статический класс Logger (его нельзя вызывать из экземпляров, только статически). Верный? – koenpeters

+0

Да, это правильно. – pangratz

+2

Хорошо. Спасибо, что пролил свет. Мне было трудно понять это (как в: Я не понял) из документации по адресу http://emberjs.com/documentation/. – koenpeters

0

reopen изменения прототипа и, таким образом, изменяет экземпляры класса

reopenClass изменяет конструктор сам и таким образом изменяет класс путем создания статические свойства и функции, которые являются , доступны только для класса, но не для всех экземпляров класса.

Обратите внимание, что изменения, внесенные reopen вступают в силу только после вызова .create()

примеры кода на основе док:

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