24

ember.jsのopenClassの機能がよくわかりません。オブジェクトのプロトタイプに余分なコードを追加したので、そのオブジェクトのすべてのインスタンスは、非静的な方法で追加された機能を取得できると思いました。ただし、これは行いません。静的に実行できるコードのみを追加しているようです。例えば。私はこのコードを持っています:

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)

私の質問は次のとおりです:openClassは何をし、いつ使用しますか?

4

2 に答える 2

45

一般に、reopenメソッドとプロパティをインスタンスに追加し、reopenClassメソッドとプロパティをクラスに追加します。

対応するテストはember-runtime/tests/system/object/reopen_test.jspackages/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('----');

</p>

于 2012-04-22T18:12:47.903 に答える
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
于 2015-04-20T03:50:50.410 に答える