动态列和行与knockoutjs



下面代码的输入参数只是一个表名,

我能够查询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可以是一个可观察对象或原始值。一定要通读映射插件文档的高级部分,你可能会发现其他有用的东西。
HTML

<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>

指出:

    唯一需要$root的地方是在<tr data-bind="foreach: $root.columns">绑定中。其他的只是为了保持一致性。
  • $parentforeach: $root.rows中的行。
  • $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>

相关内容

  • 没有找到相关文章

最新更新