带有knockoutjs的动态列和行 [英] dynamic column and rows with knockoutjs

查看:20
本文介绍了带有knockoutjs的动态列和行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

我可以查询到json格式的数据返回,但是,我无法显示我的行数据项.知道我做错了什么吗?

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>

推荐答案

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 可以是可观察值或原始值.
  • 请务必通读映射插件文档的高级部分,您可能会寻找其他有用的信息.
  • Using jQuery's .when() and .then() ensures that view model processing occurs only after both HTML requests have returned successfully. See jQuery's documentation on the topic.
  • The key function in the custom mapping ensures that when you call load() again then only the appropriate parts of your view model get an update. Otherwise ko.mapping.fromJS will replace the entire observable, resulting in a complete re-build of the affected part of your page. Specifying key allows partial page updates, so use a unique property of your data here. (If you don't plan on refreshing data from the server during page life time this step might not be necessary.)
  • The use of ko.utils.unwrapObservable() is mandatory because during a load operation key will be used on both the existing view model contents and the server response, so for example data.ColumnName could be an observable or a raw value.
  • Be sure to read through the advanced section of the mapping plugin documentation, you might find other helpful bits.

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 是可观察的,并且在复杂绑定中它们不会自动解包.
  • The only place where $root is actually necessary is in the <tr data-bind="foreach: $root.columns"> binding. The others are just included for consistency.
  • $parent refers to the row from foreach: $root.rows.
  • The parentheses in $parent[ColumnName()] are necessary because ColumnName is an observable and in a complex binding they are not unwrapped automatically.

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

The whole thing can be seen here: http://jsfiddle.net/Tomalak/A6T8p/
and here (extended version): http://jsfiddle.net/Tomalak/A6T8p/1

这篇关于带有knockoutjs的动态列和行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆