Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript显示模块模式-在函数返回后显示初始化变量_Javascript_Knockout.js_Revealing Module Pattern - Fatal编程技术网

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

Javascript显示模块模式-在函数返回后显示初始化变量,javascript,knockout.js,revealing-module-pattern,Javascript,Knockout.js,Revealing Module Pattern,我一直在使用Javascript显示模块模式,我喜欢它在公共接口和内部之间的清晰分离。然而,我不断遇到这样的情况,这让我怀疑我的总体使用模式是否正确,或者我是否应该使用该模式的某些变体 问题是,当传递到模块的init函数中并私下存储以供内部使用的内容也需要公开时,可以在敲除绑定表达式或其他模块中公开。模块的return语句立即执行,稍后调用init函数,通常传递一些动态参数,如Razor视图中脚本块中呈现的ajaxurl或原始JSON。因为模块的return语句只返回私有变量的副本而不是引用,所

我一直在使用Javascript显示模块模式,我喜欢它在公共接口和内部之间的清晰分离。然而,我不断遇到这样的情况,这让我怀疑我的总体使用模式是否正确,或者我是否应该使用该模式的某些变体

问题是,当传递到模块的init函数中并私下存储以供内部使用的内容也需要公开时,可以在敲除绑定表达式或其他模块中公开。模块的return语句立即执行,稍后调用init函数,通常传递一些动态参数,如Razor视图中脚本块中呈现的ajaxurl或原始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()访问它们。然而,这会变得非常混乱,特别是如果变量本身是一个函数,并且是一个敲除可观测变量,因此要对其求值,我需要使用双括号,如productsModule.getMyObservable()


有没有更好的方法来获取最新的内部值,使用至少接近显示模块模式的东西

基本类型按值传递,对象按引用传递;您可以利用此漏洞,只需更新
productsModule
中的
URL
。这样,在初始模块调用中返回的引用保持最新。我已经更新了你的代码来说明我的意思

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

虽然我不完全喜欢这样的想法,即必须遍历对象的所有可能级别来合并它们,但是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/

为什么不让URL成为可观察的属性

看看我的例子:


问候。

对象是通过引用传递的,如果说所有对象都是通过值传递的,但对象的值是引用,会更好吗?啊,现在你让我头疼了;)我不确定这实际上说明了什么不同。如果它是一个引用,您是否希望输出
“不是值”
?我不是100%确定,但我相信会有人突然出现并给出明确的答案。这个问题在这一点上非常好:“传入的项是按值传递的。但按值传递的项本身就是一个引用。”谢谢@TomHall。这种行为相当普遍;PHP的功能完全相同(但是有第三个选项可以显式地通过引用传递,这将解决这个问题)。它通常被描述为通过引用传递对象,但显然这也不完全正确。如果您只传递简单对象,那么合并的开销很小,但这似乎更好。我很厚颜无耻地接受我自己的答案,但感谢您为我指明了正确的方向。@TomHall:接受您自己的答案很好。在回答中写一个问题不是。在Knockout.js的世界中,对于某些属性来说,这可能是一个合理的选择,尽管这似乎有点像不必要的开销(订阅)和括号,只是为了避开RMP的尴尬流程。通常,我的模块会公开一个沉重的顶层视图模型,我不想看到它本身,只想看到它及其子视图模型的属性。但还是有好的想法。
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();​