当我搜索时,我发现,如何将viewmodel中的值绑定到view而不是viewmodel to viewmodel 我需要将一个属性值从一个viewmodel传递到另一个viewmodel,因为我需要在第一个viewmodel中更新初始属性,然后我想在另一个viewmodel中使用它。因为它在测试时很有用。
假设下面的视图模型是第一个视图模型,
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)属性值,因为要正确运行我的应用程序并让我的测试通过
答案 0 :(得分:1)
您可以使第二个视图模型依赖于您的第一个视图模型。
//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,查看这些参考文献。
http://www.knockmeout.net/2012/05/using-ko-native-pubsub.html
答案 1 :(得分:0)
这取决于两个视图模型是否在内存中并且可以同时使用。如果是这样,那么scaryman建议使用knockout-postbox是一个很好的建议。或者,您可以使用客户端消息总线,例如postal.js(这是我使用的)。
如果视图模型不在内存中并且同时可用,那么引入第三个静态对象(我们将其称为“Z”)将是必要的,以处理类似于的内容事件聚合器模式。从本质上讲,viewmodel-1会直接引用Z来存储isTested
值。当viewmodel-2实例化时,它将检查Z以获取isTested
值。这种方法实际上并不是事件的聚合,因为你不是在一个频道上发布消息(但是,如果你采取将有效载荷发送到Z的消息的方法,那么它会比它需要的方式更复杂)在这种情况下)。
如果您正在使用AMD - 比如说,需要 - 您只需要在每个视图模型中使用Z(或者实际上,在每个视图模型中依赖于Z)。您可以在http://www.requirejs.org了解有关需求的信息。
裸骨,我们会:
<强>视图模型-1 强>
this.isTested = ko.observable(false);
var Z = require("Z");
Z.isTested(this.isTested());
<强>视图模型-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可以处理一组视图模型,也许是一个字典对象可以查找有问题的视图模型。
但是,我会谨慎对待scaryman的做法,即让视图模型相互依赖。如果您有许多具有isTested
关系的视图模型,则依赖关系图可能变得非常毛茸茸。我会将isTested
和其他属性集中在一个第三方模块中:Z。
我要重申Z应该是静态的。这意味着它应该返回一个对象文字,而不是一个构造函数。
作为最后一点,顺便说一句,我不建议Mediator模式。我并不是说Z应该存储对viewmodel-1和viewmodel-2中每一个的引用。
答案 2 :(得分:-1)
我会使用事件聚合器模式,这是一种解耦且功能强大的方式,任何侦听器都可以在不与发布者联系的情况下收听任何事件。
您可以查看我是如何为此库(SignalR库)
做的https://github.com/AndersMalmgren/SignalR.EventAggregatorProxy/
为方便起见,我只提取了客户端代码
基本上你对pub / sub做的是
signalR.eventAggregator.subscribe(Event, listener.onEvent, listener);
setInterval(function() {
signalR.eventAggregator.publish(new Event(new Date()));
}, 500);
setTimeout(function() {
signalR.eventAggregator.unsubscribe(listener);
}, 5000);