淘汰赛:多个视图模型订阅 Json
Knockout: multiple view models subscribe to Json
我希望能够像这样组织我的 Knockout 代码:
- 导入一个 'Master Json' 文件并映射它。
- 创建多个视图模型,每个视图模型引用 'Master Json' 文件的特定部分。
- 将每个视图模型中的所有可观察对象绑定到 'Master Json' 文件的值。
是否可以使用ko.subscribable让所有内容订阅我的json文件作为主值?
或者如何从每个视图模型函数内部移动 $.getJSON(并保存)函数?我可以创建一个函数,以便 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 文件。当我尝试移动它时,出现一切未定义的错误。
也许这是完全错误的做法。每个人都把所有东西都放在一个视图模型中吗?它不会很快变得混乱吗?
让我创建一个进一步对话的起点:
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);
有误请指正
更新 1
创建者函数:
function getFruitViewModel(modelUrl, targetModelHolder, creator) {
$.getJSON(modelUrl, function(allData) {
targetModelHolder(creator(allData));
});
}
用法:
getFruitViewModel("json/masterJson.json", applesViewModel, function(data) { return new ApplesViewModel(data); });
是的,您可以为此使用 ko.subscribable
,如果您这样做,请查看 ko.postbox,ko.subscriable
的实用程序包装器。这将允许您跨视图模型发布您的json。
因此使用 ko.postbox
,您将发布 并订阅 events/topics。为从服务器加载 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参考。
我希望能够像这样组织我的 Knockout 代码:
- 导入一个 'Master Json' 文件并映射它。
- 创建多个视图模型,每个视图模型引用 'Master Json' 文件的特定部分。
- 将每个视图模型中的所有可观察对象绑定到 'Master Json' 文件的值。
是否可以使用ko.subscribable让所有内容订阅我的json文件作为主值?
或者如何从每个视图模型函数内部移动 $.getJSON(并保存)函数?我可以创建一个函数,以便 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 文件。当我尝试移动它时,出现一切未定义的错误。
也许这是完全错误的做法。每个人都把所有东西都放在一个视图模型中吗?它不会很快变得混乱吗?
让我创建一个进一步对话的起点:
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);
有误请指正
更新 1
创建者函数:
function getFruitViewModel(modelUrl, targetModelHolder, creator) {
$.getJSON(modelUrl, function(allData) {
targetModelHolder(creator(allData));
});
}
用法:
getFruitViewModel("json/masterJson.json", applesViewModel, function(data) { return new ApplesViewModel(data); });
是的,您可以为此使用 ko.subscribable
,如果您这样做,请查看 ko.postbox,ko.subscriable
的实用程序包装器。这将允许您跨视图模型发布您的json。
因此使用 ko.postbox
,您将发布 并订阅 events/topics。为从服务器加载 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参考。