2012-10-26 1 views
6

私はJavascript Revealing Moduleパターンを多用していました。私はパブリックインターフェイスと内部の間の明確な分離が好きです。しかし私は、私の全体的な使用パターンが正しいかどうか、またはパターンのいくつかの変形を使用すべきかどうか疑問に思うような状況に陥っています。Javascript Revealing Moduleパターン - 関数が返された後の初期化変数を公開する

問題は、モジュールのinit関数に渡され、内部使用のために非公開で保存されたものが、Knockoutバインディング式または他のモジュールのいずれかで公開される必要がある場合です。モジュールのreturn文はすぐに実行され、後でinit関数が呼び出されます。通常、Razorビュー内のスクリプトブロックにレンダリングされたAjax URLやraw JSONなどの動的パラメータが渡されます。モジュールのreturn文は、参照ではなくprivate変数のコピーを返すだけなので、init関数内のprivate変数ですでに返されたものを変更することはできません。

var productsModule = function() { 

var urls; 

var init = function(ajaxUrls) { 
    urls = ajaxUrls; 
}; 

return { 
    init: init, 
    urls: urls, 
    getUrls: function() { return urls; } 
}; 

}(); 

var customersModule = function() { 

var doSomethingWithProductsModule = function() { 
    alert(productsModule.urls); // undefined 
    alert(productsModule.getUrls()); // object 
} ;  

return { 
    doSomethingWithProductsModule: doSomethingWithProductsModule 
}; 

}(); 

var urls = { 
getProduct: '/Product/' 
}; 

productsModule.init(urls); 

customersModule.doSomethingWithProductsModule(); 

マイ回避策)だけの機能で、このような「URLの」などのオブジェクトをラップして、productsModule.getUrls(経由でそれらにアクセスすることです。しかし、それは非常に乱雑になります。特に、変数がノックアウト観測値であり、それ自体が関数なので、評価するためにproductsModule.getMyObservable()()のような二重括弧を使用する必要があります。

最新の内部値を得るには、少なくとも明らかにするモジュールパターンに近いものを使用する方が良いですか?

答えて

2

私は完全にそのようにそれらをマージする私のオブジェクトのすべての可能なレベルを反復処理することのアイデアのように、エル・ヨボの答えは、モジュール関数自体の結果を作ることを考え私を得ていないが、プロパティを更新できるローカル変数。

var productsModule = function() { 

var urls; 

var init = function(ajaxUrls) { 
urls = ajaxUrls; 
result.urls = urls; 
}; 

var result = { 
init: init, 
urls: urls 
}; 

return result; 

}(); 


// Before init 
alert(productsModule.urls); // undefined 

var urls = { 
getProduct: '/Product/' 
}; 

productsModule.init(urls); 

alert(productsModule.urls.getProduct); // /Product/ 
+0

単純なオブジェクトを渡すだけの場合は、マージするオーバーヘッドが最小限に抑えられますが、これはよりよく見えます。 –

+0

私自身の答えを受け入れるために私の奇妙な、しかし正しい方向に私を指してくれてありがとう。 –

+0

@TomHall:あなた自身の答えを受け入れても問題ありません。答えに質問を書くことはできません。 –

2

基本型は、オブジェクトが参照渡しされる間に値渡しされます。これを悪用すると、urlsproductsModuleに上書きするだけで更新できます。このようにして、最初のモジュール呼び出しで返された参照は最新のままです。私はあなたのコードを更新して、私が意味することを示しています。

var productsModule = function() { 

var urls = {}; 

var init = function(ajaxUrls) { 
    // Merge properties into the original object instead; more robust approach 
    // may be needed 
    for (name in ajaxUrls) { 
     if (ajaxUrls.hasOwnProperty(name)) { 
      urls[name] = ajaxUrls[name]; 
     } 
    } 
}; 

return { 
    init: init, 
    urls: urls, 
    getUrls: function() { return urls; } 
}; 

}(); 

var customersModule = function() { 

var doSomethingWithProductsModule = function() { 
    alert(productsModule.urls); // undefined 
    alert(productsModule.getUrls()); // object 
} ; 

return { 
    doSomethingWithProductsModule: doSomethingWithProductsModule 
}; 

}(); 

var urls = { 
    getProduct: '/Product/' 
}; 

productsModule.init(urls); 

customersModule.doSomethingWithProductsModule(); 
+0

*オブジェクトは参照で渡されます*、すべてが値渡しですが、オブジェクトの値は参照です*? – alex

+0

今、私の頭が傷ついています;)実際に違うことを言っているのかどうかはわかりません。 –

+0

参照の場合、[this jsfiddle](http://jsfiddle.net/KdgRP/)には値 "ではない"と出力されると思いますか?私は100%確信していませんが、私は誰かがポップアップし、明確な答えを与えると確信しています。 – alex

1

なぜあなたは観測可能なプロパティを作成しませんか?私の例で

ルック:

http://jsfiddle.net/Razaz/zkXYC/1/

var productsModule = function() { 

    var urls=ko.observable(); 

    var init = function(ajaxUrls) { 
     urls(ajaxUrls); 
    }; 

    return { 
     init: init, 
     urls: urls, 
     getUrls: function() { return urls(); } 
    }; 

}(); 

var customersModule = function() { 

    var doSomethingWithProductsModule = function() { 
     alert(productsModule.urls()); // undefined 
     alert(productsModule.getUrls()); // object 
    };  

    return { 
     doSomethingWithProductsModule: doSomethingWithProductsModule 
    }; 

}(); 

var urls = { 
    getProduct: '/Product/' 
}; 

productsModule.init(urls); 

customersModule.doSomethingWithProductsModule();​ 

ご挨拶。

+0

Knockout.jsの世界では、おそらくRMPの厄介な流れを回避するために不必要なオーバーヘッド(サブスクリプション)や角かっこのように見えるかもしれませんが、いくつかのプロパティでは妥当なオプションです。しばしば私のモジュールは、私自身が観測したくない重いトップレベルのビューモデル、そのプロパティとその子ビューモデルのものだけを公開します。それにもかかわらず、良い考え方。 –

関連する問題