knockout.js Javascript显示模块模式-在函数返回后显示初始化变量

yfjy0ee7  于 2022-11-29  发布在  Java
关注(0)|答案(3)|浏览(151)

我一直在使用Javascript Revealing Module模式,我喜欢它在公共接口和内部之间提供的清晰分离。然而,我不断遇到一种情况,这让我怀疑我的整体使用模式是否正确,或者我是否应该使用该模式的一些变体。
问题是当传递到一个模块的init函数中并为内部使用而私下存储的东西也需要公开时,无论是在Knockout绑定表达式中还是在其他模块中。模块的return语句立即执行,稍后init函数被调用,通常会传递一些动态参数,如 AJAX URL或Razor视图内脚本块中呈现的原始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();

我的解决方法是将诸如“urls”之类的对象 Package 在函数中,然后通过productsModule.getUrls()访问它们。然而,这会变得非常混乱,特别是当变量是一个本身就是函数的Knockout可观测变量时,因此要对其求值,我需要使用双括号,如productsModule.getMyObservable()()
有没有更好的方法来获得最新的内部值,使用某种至少近似于揭示模块模式的东西?

w7t8yxp5

w7t8yxp51#

基本类型通过值传递,而对象通过引用传递;您可以利用这一点,这样您就可以更新productsModule中的urls,而不是覆盖它。这样,初始模块调用中返回的引用就可以保持最新。我已经更新了您的代码来说明我的意思。

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

xmq68pz92#

虽然我不太喜欢必须遍历对象的所有可能级别才能像那样合并它们的想法,但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/
q8l4jmvw

q8l4jmvw3#

为什么不把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();​

你好。

相关问题