这是一个 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
和一个方法,并通过在.getConfiguration
data-bind="change: getConfiguration
select
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));
});
在这方面取得了更大的成功(尽管不确定我是否需要从视图模型中删除模板列表)-但现在出现以下错误 [您不能将绑定多次应用于同一元素。]。