var modules;
$.when(
$.get('modules.json', function(data) {
var mapping = { 'observe' : ['enabled'] };
modules = ko.mapping.fromJS(data, mapping);
})
).then(function() {
ko.applyBindings(new viewModel(modules));
});
function viewModel(modules) {
var self = this;
self.modules = modules;
console.log(self.modules());
...
}
json数组中每个模块对象中的enabled
键值不应该在我的控制台中显示为可观察的函数,其值设置为json中定义的值(在本例中为{{1} })?
此外,等待绑定收到的json数据的方式比我现在尝试的方式更好(如果有更好的方法)?
我的json数组中的对象如下所示:
true
另外,我如何利用{
"id" : "spnsrlogo",
"name" : "Sponsor Logo",
"code" : "<h3>Sponsor Logo</h3><label for=\"spnsrLogoSrc\" data-bind=\"text: $root.spnsrLogoSrc\">Sponsor Logo Path</label><input type=\"text\" id=\"spnsrLogoSrc\" data-bind=\"value: $root.spnsrLogoSrc, valueUpdate: 'afterkeydown'\">",
"output" : "assets/img/sponsor-logo.png",
"enabled" : true
}
值,以便在追加时,observable变为活动状态?请将此非工作尝试视为示例:
code
我尝试将modulesEnabled变成一个可观察的数组但是没有用。
非常感谢任何帮助!
答案 0 :(得分:1)
对于问题的第一部分,我查看了映射源。在here附近,处理观察设置。它的工作原理是将属性的“完整路径”与您在observe数组中传递的字符串完全匹配。
使用json层次结构时,启用的属性应指定为[0] .enabled,[1] .enabled,[2] .enabled等。目前我认为你必须在数组中完全按照它传递它们,也许我们应该问一个插件维护者是否可以改为类似[i] .enabled,以考虑数组的所有成员。如果任何维护者/ hardcore_users读到这个:伙计们,我是否正确?
因此,您必须生成'observe'配置数组,使其与初始数据中的项目数一样长,如下所示:
var mapping = { 'observe' : ['[0].enabled', '[1].enabled', '[2].enabled',.../*and so on*/ ] };
改变你的json结构可能会更好。
对于问题的第二部分,可以使用自定义绑定完成,如下所示:
ko.bindingHandlers.customHtml = {
init:function(element, valueAccessor, allBindings, viewModel, bindingContext){
$(element).html(valueAccessor());
ko.applyBindingsToNode($(element).find("div")[0],{with:viewModel}, bindingContext.$root );
return { controlsDescendantBindings: true };
},
update:function(element, valueAccessor, allBindings, viewModel, bindingContext){
}
}
请注意,我添加了一些div标签来将html包装在代码属性中。
页面中的初始html改变如此,我只添加了customHtml customBinding:
<div id="modulecontainer" data-bind="foreach: modules">
<div class="moduleoptions" data-bind="visible: $parent.modulesEnabled(), customHtml: code, attr: { id: 'module-' + $data.id}"></div>
</div>
最后,所有代码的小提琴:http://jsfiddle.net/cUVN8/3/
答案 1 :(得分:0)
如果有人有兴趣,我终于设法让事情奏效了。我要感谢pax162的第二个答案,因为如果没有它,我就会迷失方向。
我最终构建了我的JSON:
{
"id" : "isi",
"name" : "ISI",
"code" : "<h3>ISI</h3><label for=\"isiHeading\">ISI Heading</label><input type=\"text\" id=\"isiHeading\" data-bind=\"value: isiHeading, valueUpdate: 'afterkeydown'\"><label for=\"isiContent\">ISI Content</label><textarea id=\"isiContent\" data-bind=\"value: isiContent, valueUpdate: 'afterkeydown'\"></textarea><label for=\"isiFooter\">ISI Footer HTML</label><textarea id=\"isiFooter\" data-bind=\"value: isiFooter, valueUpdate: 'afterkeydown'\"></textarea>",
"observables" : ["isiHeading","isiContent","isiFooter"]
}
然后使用一些延迟的jQuery魔术并手动添加我的observables:
$.when(
$.get(options.paths.modules, function(data) {
self.modules = data;
for (var i=0, l=self.modules.length; i<l; i++) {
if (typeof(data[i].observables) !== "undefined") {
for (var j=0, ll=data[i].observables.length; j<ll; j++) {
self.modules[i][data[i].observables[j]] = ko.observable('');
}
}
self.modules[i].enabled = ko.observable(true);
}
})
).then(function() {
self.successful();
ko.applyBindings(self);
}, function(o) {
console.log(o);
});
如果有人好奇,我的成功函数包含customHtml绑定处理程序定义和我在其他地方使用的其他更通用的observable的创建(不依赖于收到的JSON):
this.successful = function() {
ko.bindingHandlers.customHtml = {
init: function(element,valueAccessor,allBindings,viewModel,bindingContext) {
$(element).html(valueAccessor());
ko.applyBindingsToNode($(element)[0],{with:viewModel}, bindingContext.$root);
return { controlsDescendantBindings: true };
},
update: function(element,valueAccessor,allBindings,viewModel,bindingContext) {
//
}
};
// other functionality not relevant to this problem
};