6

私は Javascript Revealing Module パターンを頻繁に使用しており、パブリック インターフェイスと内部を明確に分離できる点が気に入っています。しかし、全体的な使用パターンが正しいかどうか、またはパターンの変形を使用する必要があるかどうか疑問に思う状況に遭遇し続けています。

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

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() を介してそれらにアクセスすることです。ただし、変数がそれ自体が関数である Knockout オブザーバブルである場合は特に、これは非常に厄介になります。そのため、変数を評価するには、productsModule.getMyObservable()() のような二重括弧を使用する必要があります。

明らかにモジュールパターンに少なくとも近似するものを使用して、最新の内部値を取得するより良い方法はありますか?

4

3 に答える 3

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();
于 2012-10-26T03:26:02.720 に答える
2

オブジェクトのすべての可能なレベルを反復処理してそのようにマージする必要があるという考えは完全には好きではありませんが、El Yobo の回答により、モジュール関数自体の結果を、プロパティを更新できるローカル変数にすることを考えるようになりました。 .

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/
于 2012-10-26T07:19:05.287 に答える
1

URLを監視可能なプロパティにしないのはなぜですか?

私の例を見てください:

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();​

ご挨拶。

于 2012-10-26T10:22:34.450 に答える