我正在尝试将我的Asp.Net Web API控制器中的模型加载到我的ViewModel(其中包含一个包含列表的列表的模型......非常复杂)。
.Net模型是:
public class PlateTemplateExtendedDto
{
public int Id { get; set; }
public string Description { get; set; }
public decimal Height { get; set; }
public decimal Width { get; set; }
public List<PlateTemplateGroupDto> PlateTemplateGroups { get; set; } = new List<PlateTemplateGroupDto>();
}
该类中的List项声明为:
public class PlateTemplateGroupDto
{
public int Id { get; set; }
public string Description { get; set; }
public List<PlateTemplateGroupComponentDto> Components { get; set; } = new List<PlateTemplateGroupComponentDto>();
}
然后在THAT列表中,作为对象:
public class PlateTemplateGroupComponentDto
{
public int Id { get; set; }
public int PlateTemplateGroupId { get; set; }
public int GroupComponentTypeId { get; set; }
public string GroupComponentType { get; set; }
public int EntryDisplayOrderId { get; set; }
}
这是我的一些View模型。 “数据”是我想要保存数据模型的字段,并将其发回。
function TemplateViewModel() {
var self = this;
self.Data = ko.observable();
self.TemplateId = ko.observable($("#InputTemplateId").val());
self.CreateMode = ko.observable(!!self.TemplateId() == false);
self.loadData = function () {
$.get("/api/Template/Get", { id: self.TemplateId() }).done(function (data) {
self.Data(ko.mapping.fromJS(data));
alert(self.Data().PlateTemplateGroups().length);
});
}
self.save = function () {
var data = ko.mapping.toJS(self.TemplateGroups);
$.post("/api/Template/Save", data).done(function (result) {
alert(result);
});
};
if (!self.CreateMode()) {
self.loadData();
}
}
加载后的警报......如果我闯入代码,我可以看到Data拥有我期望的模型。
但是,当我尝试在视图上使用它时,它会失败:
<ul class="nav nav-tabs" data-bind="foreach: Data().PlateTemplateGroups()">
<li data-bind="css: {active: $index()==0}"><a data-toggle="tab" data-bind="attr: {href: ('#tabId' + $index())}"><span data-bind="text: Description"></span></a></li>
</ul>
什么都没发生。这是因为某些事情尚未初始化吗?甚至可以这样做吗?控制台窗口中出现错误:
未捕获的TypeError:无法处理绑定“foreach:function (){return Data()。PlateTemplateGroups()}“消息:无法读取 属性'PlateTemplateGroups'未定义
事实上,在从api调用加载后,我可以看到模型中的所有数据:
self.Data()。PlateTemplateGroups()[0] .Components()
它显示了PlateTemplateGroups列表中的第一个项目,我可以看到'Components'中的项目(这也是一个列表。这一切看起来都是可观察的,因为我将它们作为函数访问。
我的视图模型applybindings发生在我的js文件的末尾:
function PlateTemplateViewModel() {
var self = this;
....
}
$(document).ready(function () {
ko.applyBindings(new PlateTemplateViewModel(), $("#plateTemplate")[0]);
});
答案 0 :(得分:2)
您在浏览器控制台中有错误吗?你确定PlateTemplateGroups是可观察的字段吗?
请在渲染之前向我们展示api响应示例和viewModel状态
function TemplateViewModel() {
var self = this;
self.Data = ko.observable({PlateTemplateGroups: ko.observableArray()});
//....
您的代码的执行计划:
致电new TemplateViewModel()
,
致电self.loadData
致电applyBindings // in this moment data didn't return from the server and ko throw error
,
调用loadData函数的'done'回调
您应该预先启动viewModel或调用applyBinding作为回调:
self.loadData = function (callback) {
$.get("/api/Template/Get", { id: self.TemplateId() }).done(function (data) {
self.Data(ko.mapping.fromJS(data));
alert(self.Data().PlateTemplateGroups().length);
if(typeof callback === 'function')
callback();
});
}
不在视图模型构造函数中调用loadData
$(document).ready(function () {
var viewModel = new PlateTemplateViewModel();
if (!viewModel.CreateMode()) {
viewModel.loadData(function(){
ko.applyBindings(viewModel, $("#plateTemplate")[0]);
});
}
});