下面代码的输入参数只是一个表名,
我能够查询json格式的数据返回,但是,我无法显示数据的行项。知道我做错了什么吗?
<script>
var invtype = "@ViewBag.invtype";
function ViewModel() {
var self = this;
function ColName(tbstruct){
this.ColumnName = tbstruct.ColumnName
}
self.TBStruct = ko.observableArray();
self.items = ko.observableArray();
self.invtype = invtype;
self.Load = function () {
//expected data for self.items
//[{"$id":"1","Id":2,"Inv_Id":"PV0001-1","ACX_No":"6","ACX_Name":"ABC","S_No":"5", "Acc_Class":"Local","Direction":"Two-Way"},{"$id":"2","Id":2,"Inv_Id":"PV0002-1","ACX_No":"3","ACX_Name":"CKD","S_No":"6", "Acc_Class":"Local","Direction":"Two-Way"}]
$.ajax({
url: "@Url.Content("~/api/")"+self.invtype,
type: 'GET',
dataType: 'JSON',
success: function (data) {
// Map the returned JSON to the View Model
self.items = data;
}
});
//expected data
//[{"$id":"1","ColumnName":"Id","system_type_id":56,"primaryCol":1}, {"$id":"2","ColumnName":"Inv_Id","system_type_id":231,"primaryCol":0},{"$id":"3","ColumnName":"ACX_No","system_type_id":175,"primaryCol":0},{"$id":"4","ColumnName":"ACX_Name","system_type_id":175,"primaryCol":0},{"$id":"5","ColumnName":"S_No","system_type_id":175,"primaryCol":0} {"$id":"27","ColumnName":"Acc_Class","system_type_id":231,"primaryCol":0},{"$id":"28","ColumnName":"Direction","system_type_id":231,"primaryCol":0} ]
$.ajax({
url: "@Url.Content("~/api/inventories/")"+self.invtype,
type: 'GET',
dataType: 'JSON',
success: function (data) {
// Map the returned JSON to the View Model
$.each(data,function(i,dt){
//console.log(dt.ColumnName);
self.TBStruct.push(new ColName(dt));
});
//console.dir(self.TBStruct);
}
});
return self;
};
}
var View = new ViewModel();
ko.applyBindings(View.Load());
这里我试着把它们显示出来。
<thead>
<tr data-bind="foreach: TBStruct">
<th data-bind="text: ColumnName"></th>
</tr>
</thead>
<tbody >
<tr data-bind="foreach: items" >
<td data-bind="text:$data"></td>
</tr>
</tbody>
</table>
function ViewModel() {
var self = this;
self.invtype = "@ViewBag.invtype";
self.columns = ko.observableArray();
self.rows = ko.observableArray();
self.load = function () {
$.when(
$.get("@Url.Content('~/api/inventories/')" + self.invtype),
$.get("@Url.Content('~/api/')" + self.invtype)
)
.then(function (columnResponse, rowResponse) {
var columnDefs = columnResponse[0],
rowDefs = rowResponse[0],
columnMapping = {
key: function (data) {
return ko.utils.unwrapObservable(data.ColumnName);
}
},
rowMapping = {
key: function (data) {
return ko.utils.unwrapObservable(data.Id);
}
};
ko.mapping.fromJS(columnDefs, columnMapping, self.columns);
ko.mapping.fromJS(rowDefs, rowMapping, self.rows);
});
return self;
};
}
指出:
- 使用jQuery的
.when()
和.then()
确保视图模型处理只发生在两个HTML请求成功返回后。参见jQuery的文档。 - 自定义映射中的
key
函数确保当您再次调用load()
时,只有视图模型的适当部分得到更新。否则,ko.mapping.fromJS
将替换整个可观察对象,导致页面受影响部分的完全重新构建。指定key
允许部分页面更新,因此在这里使用数据的唯一属性。(如果不打算在页面生命周期内从服务器刷新数据,则可能不需要执行此步骤。)
ko.utils.unwrapObservable()
的使用是强制性的,因为在加载操作期间,key
将同时用于现有的视图模型内容和服务器响应,因此,例如data.ColumnName
可以是一个可观察对象或原始值。一定要通读映射插件文档的高级部分,你可能会发现其他有用的东西。<table>
<thead>
<tr data-bind="foreach: $root.columns">
<th data-bind="text: ColumnName"></th>
</tr>
</thead>
<tbody data-bind="foreach: $root.rows">
<tr data-bind="foreach: $root.columns">
<td data-bind="text: $parent[ColumnName()]"></td>
</tr>
</tbody>
</table>
指出:
- 唯一需要
-
$parent
为foreach: $root.rows
中的行。
$root
的地方是在<tr data-bind="foreach: $root.columns">
绑定中。其他的只是为了保持一致性。$parent[ColumnName()]
中的括号是必要的,因为ColumnName
是一个可观察对象,在复杂的绑定中,它们不会自动展开。整件事可以在这里看到:http://jsfiddle.net/Tomalak/A6T8p/
和这里(扩展版):http://jsfiddle.net/Tomalak/A6T8p/1
重写my self.load
self.Load = function () {
$.ajax({
url: "@Url.Content("~/api/")"+self.invtype,
type: 'GET',
dataType: 'JSON',
success: function (data) {
// Map the returned JSON to the View Model
ko.mapping.fromJS(data,{}, self.items);
}
});
$.ajax({
url: "@Url.Content("~/api/inventories/")"+self.invtype,
type: 'GET',
dataType: 'JSON',
success: function (data) {
// Map the returned JSON to the View Model
$.each(data,function(i,dt){
self.TBStruct.push(new ColName(dt));
});
}
});
return self;
};
下面迭代的输出 <thead>
<tr data-bind="foreach: TBStruct">
<th data-bind="text: HeaderName,visible: SystemField == -1 || Visible" ></th>
</tr>
</thead>
<tbody data-bind="foreach: items " >
<tr data-bind="foreach: $root.TBStruct, click:function() { alert('me');}" id="rowData">
<td data-bind="text: $parent[ColumnName],visible: SystemField == -1 || Visible" ">
</td>
</tr>
</tbody>