映射值不可观察等

时间:2013-11-04 21:23:44

标签: knockout.js

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变成一个可观察的数组但是没有用。

非常感谢任何帮助!

2 个答案:

答案 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

};