0

私が取り組んでいるアプリケーション ドメインの同様のエンティティをすべて処理するための基本的なモデルを考え出す際に、以下を作成しました。

  • 基本オブジェクト (エンティティ): いくつかの共有プロパティと初期化子を持ち、プロトタイプとして設定されます
  • 製品オブジェクト (Product): Entity から「継承」します。「バリアント」のリストが含まれています
  • バリアント オブジェクト (Variant): Entity から "継承" します。

Product.prototype = 新しいエンティティ();

Variant.prototype = 新しいエンティティ ();

これを実行すると、奇妙なことが起こります。「product」オブジェクトの「variants」リストには、最終的に 2 つの要素が含まれます。これは問題ありませんが、これらが「Variant」の 2 つの別個のインスタンスである代わりに、同じメモリを指しています。スペース。

observableArray を埋める「for ループ」中に問題がないように、いくつかのデバッグ (アラート ベース) を行いました。

var Product = function (data) {
var initial = data || {};
this.variants = ko.observableArray();
this.init(initial);
if (initial.variants != null) {
  for (var i = 0; i < initial.variants.length; i++) {

    // NOTE: this is the misterious line. Creating two instances
    //       of 'new Variant', ends up pushing a single instance. 
    this.variants.push(new Variant(initial.variants[i]));
    //-----------------------------------------------------------
    
    alert(this.variants()[i].name());
  }
}

何が間違っているのかを理解するために、Javascriptの基本がいくつか欠けていると思います。

JsFiddleの完全なサンプルを次に示します。

4

1 に答える 1

1

オブザーバブルをプロトタイプに配置すると、それらは、独自の個別のオブザーバブルではなく、すべてのインスタンスで共有されることになります。observableは、その値を内部にキャッシュする関数です。したがって、この場合、すべてのインスタンスに同じ関数のコピーがあります。

一般に、プロトタイプにオブザーバブルを配置することは避けたいと思いますが、他の関数(ジェネラルハンドラー、サブスクリプションコールバック、および計算されたオブザーバブル読み取り/書き込み関数)を配置することはできます。

オブザーバブルを持つ別の構造を継承する構造を作成する場合は、さまざまな「ミックスイン」タイプの戦略の1つを使用することを選択できます。

たとえば、基本コンストラクターを兄弟オブジェクトに適用できます。

var Product = function(data) {
  Entity.call(this, data); //call the Entity constructor to add observables, etc.

  //do other Product stuff here
};

次に、プロトタイプをProductプロトタイプと等しくするEntityか、プロトタイプのチェーンに次のようにプロトタイプをProduct含めることができます。Entity

Product.prototype = Object.create(Entity.prototype);

古いブラウザをサポートしている場合は、Object.create シムを探してください。

更新されたサンプル:http://jsfiddle.net/rniemeyer/7AnAz/

于 2013-01-25T20:28:22.083 に答える