我把一个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));
});
在此方面取得了更大的成功(虽然不确定我是否需要从视图模型中删除模板列表) - 但现在出现以下错误[您无法多次将绑定应用于同一元素。]。
答案 0 :(得分:1)
如果您只是获得一个简单的javascript对象(我认为您的模板是),则其属性不会被淘汰视为可观察。您必须使用knockout映射插件才能使您的模板属性可观察(请参阅此处:http://knockoutjs.com/documentation/plugins-mapping.html)。
你也可以做自己的javascript“Template”对象。这样的事情:
function Template(jsonTemplate) {
this.id = ko.observable(jsonTemplate.id);
//etc.
}
然后从JSON对象构建Templates对象。