2012-04-22 8 views
24

Non ho davvero la funzione di reopenClass di ember.js. Ho pensato di aggiungere codice aggiuntivo al prototipo dell'oggetto, quindi tutte le istanze di quell'oggetto otterrebbero la funzionalità che è stata aggiunta in modo non statico. Non lo fa comunque. Sembra che aggiunga solo codice che può essere eseguito staticamente. Per esempio. Ho questo codice:Ember.js come funziona 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") 

Produce questo:

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

Quello che mi aspettavo era questo:

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

Quindi la mia domanda è: Cosa reopenClass fare e quando si usa vero?

risposta

44

In generale, reopen aggiunge metodi e proprietà per casi mentre reopenClass aggiunge metodi e proprietà per classi.

I test corrispondenti sono ember-runtime/tests/system/object/reopen_test.js e packages/ember-runtime/tests/system/object/reopenClass_test.js.

Ho aggiornato il codice e ha aggiunto alcuni commenti, vedere 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, Se ottengo questo r ight logger.reopen() aggiunge solo il codice all'istanza del logger, Logger.reopen() aggiunge il codice per ogni nuova istanza che verrà creata (le istanze esistenti non saranno modificate) e Logger.reopenClass() aggiunge il codice che è statico a la classe Logger (non può essere chiamata da istanze, solo staticamente). Corretta? – koenpeters

+0

Sì, è corretto. – pangratz

+2

Ok. Grazie per aver fatto luce. Ho avuto difficoltà a capire questo (come in: I did not get it) dalla documentazione su http://emberjs.com/documentation/. – koenpeters

0

reopen cambiamenti prototipo e cambia quindi casi di una classe

reopenClass cambia il costruttore stesso e quindi cambia la classe creando proprietà e funzioni statiche che sono disponibili solo nella classe ma non in nessuna istanza della classe.

Si noti che le modifiche introdotte dalla reopen hanno effetto solo dopo aver chiamato .create()

esempi di codice sulla base del documento:

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