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