1

My input parameter for the code below is just a tablename,

I was able to query the data return in json format, however, i am not able to display my rows item of data. any idea what did i do wrong?

<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()); 

here i am trying to display them out.

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

2 回答 2

3
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将替换整个 observable,从而导致页面受影响部分的完全重新构建。指定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">绑定。其他的只是为了一致性而包括在内。
  • $parent指来自 的行foreach: $root.rows
  • 中的括号$parent[ColumnName()]是必要的,因为ColumnName它是可观察的,并且在复杂的绑定中它们不会自动展开。

整个事情可以在这里看到:http: //jsfiddle.net/Tomalak/A6T8p/
和这里(扩展版):http: //jsfiddle.net/Tomalak/A6T8p/1

于 2013-05-03T11:42:05.273 回答
3

重写了我的 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>
于 2013-05-03T00:41:38.590 回答