1

这是一个 jsFiddle 示例

我拼凑了一个 jsFiddle 来尝试展示我想要实现的目标(反映了迄今为止的第三次尝试)。


我刚开始玩KnockoutJS,我有点难过。这就是我想做的。

我有一个 asmx 方法,它返回一个 JSON 字符串,它是以下反序列化的对象(为简洁起见,省略了大多数属性):

class Template
{
    public int Id { get; set; }
    public string Name { get; set; }
    public List<Group> Groups { get; set; }
}

class Group
{
    public string Name { get; set; }
    public List<Question> Questions { get; set; }
}

class Question
{
    public string Text { get; set; }
}

我有一个网页,select允许用户选择Template. 一旦他们选择了一个,它就会关闭并调用上述方法以返回该模板的配置。

最初,我正在使用这些模板的列表创建我的 JavaScript 视图模型,如下所示。

function viewModel(templates) {
    var self = this;
    self.templates = ko.observableArray(templates);
}

// this is just a $.ajax call to another asmx service that gets me 
// a JSON array of all templates
var templates = getTemplates();
var vm = ko.applyBindings(new viewModel(templates));

然后我的标记像这样使用它。

<select id="template" data-bind="foreach: templates">
    <option data-bind="text: Name, value: Id"></option>
</select>

到目前为止一切正常,我想我的问题是返回模板配置并将其存储在视图模型中并显示在页面上的正确方法是什么?

第一次尝试

我已经向视图模型添加了一个属性configuration和一个方法,并通过在.getConfigurationdata-bind="change: getConfigurationselect

function viewModel(templates) {
    var self = this;
    self.templates = ko.observableArray(templates);
    self.configuration = null;
    self.getConfiguration = function () {
        // calls the asmx web method, parses the returned JSON to an object
        // and then...
        self.configuration = $.parseJSON(data.d);
    };
}

但我运气不好,谁能给我一个友好的推动,朝着正确的方向发展?一如既往地感谢任何和所有帮助。

第二次尝试

根据下面mael的回答,我尝试将其设置configuration为可观察的。这是我的标记(目前只是想观察模板的名称):

<div data-bind="if: configuration">
    <strong data-bind="text: configuration.Name"></strong>
</div>

getConfiguration方法:

var config = $.parseJSON(data.d); // the ajax call to get the JSON
self.configuration = ko.observable(config);

我也用映射插件试过这个:

self.configuration = ko.mapping.fromJS(config);

虽然没有运气:s

第三次尝试

我决定放弃在我的视图模型中存储模板列表的想法,而只是单独创建这个列表。现在在我的模板列表事件中ko.applyBindings调用。.change

var viewModel = function (config) {
    var self = this;
    self.configuration = config;
}

$('#templates').unbind('change').on('change', function () {
    var id = $(this).children('option:selected').val();
    var config = getConfig(id); // calls my asmx method to get the config JSON
    ko.applyBindings(new viewModel(config));
});

在这方面取得了更大的成功(尽管不确定我是否需要从视图模型中删除模板列表)-但现在出现以下错误 [您不能将绑定多次应用于同一元素。]。

4

1 回答 1

1

如果你只是得到一个普通的 javascript 对象(我认为你的模板是),它的属性不会被淘汰赛观察到。您必须使用敲除映射插件来使您的模板属性可观察(参见此处: http: //knockoutjs.com/documentation/plugins-mapping.html)。

你也可以做你自己的javascript“模板”对象。像这样的东西:

function Template(jsonTemplate) {
    this.id = ko.observable(jsonTemplate.id);
    //etc.
}

然后从您的 JSON 对象构建模板对象。

于 2013-07-11T08:34:44.880 回答