我希望能够组织我的Knockout代码,如下所示:
是否可以使用 ko.subscribable 将所有订阅我的json文件作为主值?
或者如何从每个视图模型函数内部移动$ .getJSON(和save)函数?我可以创建一个函数,以便getJSON结果可以在每个视图模型中重复使用吗?
function ApplesViewModel ( data ) {
// ko.observables here
//Get Json
$.getJSON("json/masterJson.json", function(allData) {
var mappedSlides = $.map(allData, function(item) { return new Slide(item) });
self.slides(mappedSlides);
});
//Save Json
self.save = function() {
$.ajax("/masterJson", {
data: ko.toJSON({ slides: self.slides }),
type: "post", contentType: "application/json",
success: function(result) { alert(result) }
});
};
}
function BananasViewModel( data ) {
//same as ApplesViewModel but with different observables
}
function CarrotsViewModel( data ) {
//same as ApplesViewModel but with different observables
}
ko.applyBindings(new ApplesViewModel());
ko.applyBindings(new BananasViewModel());
ko.applyBindings(new CarrotsViewModel());
我不想多次导入它,因为我认为每次都会创建一个新副本。它应该只是一个Json文件。当我试图移动它时,我得到的错误是一切都未定义。
也许这是完全错误的做法。每个人都将所有内容都放在一个视图模型中吗它会不会很快混淆?
答案 0 :(得分:1)
让我为进一步的对话创建一个起点:
function ApplesViewModel(data) {
self.slides = ko.observableArray($.map(data, function(item) { return new Slide(item) }));
// setup other properties here
}
function getFruitViewModel(modelUrl, targetModelHolder) {
$.getJSON(modelUrl, function(allData) {
targetModelHolder(new ApplesViewModel(allData));
});
}
function saveFruitViewModel(saveModelUrl, targetModelHolder) {
$.ajax(saveModelUrl, {
data: ko.toJSON(ko.unwrap(targetModelHolder)),
type: "post", contentType: "application/json",
success: function(result) { alert(result) }
});
}
用法示例:
var applesViewModel = ko.observable();
getFruitViewModel("json/masterJson.json", applesViewModel);
// some work with view model(s)
saveFruitViewModel("/masterJson", applesViewModel);
如果我误解,请纠正我。
创作者功能:
function getFruitViewModel(modelUrl, targetModelHolder, creator) {
$.getJSON(modelUrl, function(allData) {
targetModelHolder(creator(allData));
});
}
用法:
getFruitViewModel("json/masterJson.json", applesViewModel, function(data) { return new ApplesViewModel(data); });
答案 1 :(得分:1)
是的,您可以使用ko.subscribable
,如果您这样做,请结帐ko.postbox,ko.subscriable
的实用程序包装器。这样您就可以跨视图模型发布您的json。
因此,使用ko.postbox
,您将发布和订阅到活动/主题。创建一个单独的函数,用于从服务器加载JSON,并使此发布事件,并且该事件的所有订阅者都将知道收到数据的时间。
function DataLoader(){
var self = this;
self.loadJSON = function(){
//Load JSON using getJSON from server and publish event "JsonDataLoaded"
setTimeout(function(){
ko.postbox.publish("JsonDataLoaded", data);
}, 3000)
};
}
var loader = new DataLoader();
loader.loadJSON();
因此,无论何时需要新数据,都会调用loader.loadJSON' and upon success, that will yield event/topic 'JsonDataLoaded
。然后,您可以在视图模型中订阅此事件。像
function ApplesViewModel(data) {
var self = this;
ko.postbox.subscribe("JsonDataLoaded", function(newData){
ko.mapping.fromJS(newData,{},self);
},self,true);
}
CodePen参考。