Knockout.js 在knockoutjs中将值从一个viewmodel传递到另一个viewmodel
当我搜索时,我发现了如何将值从viewmodel绑定到视图,而不是从viewmodel绑定到viewmodel 我需要将一个属性值从一个viewmodel传递到另一个viewmodel,因为我需要在第一个viewmodel中更新初始属性,然后我想在另一个viewmodel中使用它。因为它在测试时很有用 假设下面的视图模型是第一视图模型Knockout.js 在knockoutjs中将值从一个viewmodel传递到另一个viewmodel,knockout.js,Knockout.js,当我搜索时,我发现了如何将值从viewmodel绑定到视图,而不是从viewmodel绑定到viewmodel 我需要将一个属性值从一个viewmodel传递到另一个viewmodel,因为我需要在第一个viewmodel中更新初始属性,然后我想在另一个viewmodel中使用它。因为它在测试时很有用 假设下面的视图模型是第一视图模型 var xx = xx || {}; xx.yyy = xx.yyy || {}; xx.yyy.zzz = function(object )
var xx = xx || {};
xx.yyy = xx.yyy || {};
xx.yyy.zzz = function(object ) {
var model = {};
model.isTested= ko.observable(false);
//below is the anonymous call to get the value(true/false):
datasource.someFeatureEnable.isTested().done(function (featureToggle) {
model.isTested(featureToggle.enabled);
});
}
我想在另一个viewmodel中传递isTested(true/false)属性值,因为要正确运行我的应用程序并使我的测试通过,我将使用事件聚合器模式,这是一种解耦且功能强大的方式,任何侦听器都可以侦听任何事件,而无需耦合到发布者 您可以检查我是如何为这个库(信号器库)做到这一点的 为了方便起见,我提取了客户端代码 基本上你对酒吧/酒吧做的是
signalR.eventAggregator.subscribe(Event, listener.onEvent, listener);
setInterval(function() {
signalR.eventAggregator.publish(new Event(new Date()));
}, 500);
setTimeout(function() {
signalR.eventAggregator.unsubscribe(listener);
}, 5000);
可以使第二个viewmodel依赖于第一个viewmodel
//this is the definition of your first view model.
function MainViewModel(dataSource) {
var self = this;
this.DataSource = dataSource;
this.isTested = ko.observable(false);
//a callable function that will run isTested check on someFeatureEnable
this.TestSomeFeature = function() {
self.DataSource.someFeatureEnable.isTested().done(function (featureToggle) {
self.isTested(featureToggle.enabled);
});
};
return this;
}
//this is the definition of your second viewmodel
function SubViewModel(mainViewModel) {
var self = this;
self._mainViewModel = mainViewModel;
//for read only access
self.MainIsTested = function() { return self._mainViewModel.isTested(); }
//for read/write
self.MainIsTestedReference = self._mainViewModel.isTested
return self;
}
//this is the code that initializes the whole page.
var main = new MainViewModel();
var sub = new SubViewModel(main);
//now run the check
main.TestSomeFeature();
//these are examples, showing how to get at the isTested property in your various viewmodels. The comments are what the code should return
sub.MainIsTested(); //false
main.isTested(); //false
//set isTested to true from the sub
sub.MainIsTestedReference(true);
//now main isTested returns true, because the sub viewmodel and the main viewmodel have references to the same object.
main.isTested(); // true
如果您想更高级,并使用基于事件的方法,我建议您查看ko.postbox,请查看这些参考资料
这取决于两个ViewModel是否在内存中并且是否同时可用。如果是这样的话,那么斯卡里曼关于使用淘汰邮箱的建议就是一个好建议。或者,您可以使用客户端消息总线,如posal.js(我使用的就是它) 如果viewmodels不在内存中并且不同时可用,那么引入第三个静态对象(我们称之为“Z”)将有必要处理类似于事件聚合器模式的内容。实际上,viewmodel-1将直接引用Z来存储
isTested
值。当viewmodel-2实例化时,它将与Z一起检查以获得isTested
值。这种方法并不是真正的事件聚合,因为您没有在通道上发布消息(尽管,如果您采用将带有有效负载的消息发送到Z的方法,那么它将比本例中需要的复杂得多)
如果您使用AMD——比如说require——您只需要在每个viewmodel中使用Z(或者,实际上,在每个依赖于Z的viewmodel中使用Z)。你可以在网站上阅读
赤裸裸,我们会:
viewmodel-1
this.isTested = ko.observable(false);
var Z = require("Z");
Z.isTested(this.isTested());
viewmodel-2
this.isTested = false; //Making the assumption that isTested doesn't have to be observable here--but it could be
var Z = require("Z");
this.isTested = Z.isTested();
当然,您将对此进行详细说明,以便Z可以处理一组viewmodels,也许可以使用一个dictionary对象来查找所讨论的viewmodel
不过,我要对scaryman使视图模型相互依赖的方法提出警告。如果有许多viewmodels具有isTested
关系,则依赖关系图可能会变得非常复杂。我将把isTested
和其他属性集中在一个第三方模块中:Z
我重申Z应该是静态的。这意味着它应该返回一个对象文本,而不是构造函数
最后一点,顺便说一下,我不是在建议中介模式。我不是建议Z应该存储对viewmodel-1和viewmodel-2的引用。嗨,scaryman:)…感谢您的快速响应。我对上述代码不太清楚。请提及哪些代码行将成为第一视图模型的一部分,哪些代码行将成为第二视图模型的一部分?我添加了一些注释,希望代码对您来说更清晰。从你的StackOverflow分数来看,你似乎在javascript和knockout方面相对缺乏经验。我建议您在运行教程,然后,如果您想了解更多关于javascript的信息,或者了解淘汰教程中代码背后的原因,请查看。它很长,很密集,但很好的东西。确保查阅第一部分的阅读清单。