【问题标题】:knockout dynamic master details淘汰赛动态大师详情
【发布时间】:2013-05-04 10:09:24
【问题描述】:

通过 KnockoutJS 实现动态创建、读取、更新、删除

与其他专家 (dynamic column and rows with knockoutjs) 继续提问的部分内容

<script type="text/javascript">
     var columnDefs = [{
        "$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
    }];

    var rowDefs = [{
        "$id": "1",
            "Id": 1,
            "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"
    }];

    function HeaderViewModel(data, parent) {
        var self = this,
            nbsp = String.fromCharCode(160);

        // observables
        ko.mapping.fromJS(data, {}, self);
        //self.isVisible = ko.observable(true);

        // computeds
        self.isVisible = ko.computed(function () {
            //console.log('data.ColumnName.indexOf(\'SYS\'):',  data.ColumnName.indexOf('SYS'));
            return data.ColumnName.indexOf('SYS') >= 0 ? false : true;
        });
        self.HeaderName = ko.computed(function () {
            return data.ColumnName.replace('_', nbsp);
        });
        self.SystemField = ko.computed(function () {
            return data.ColumnName.indexOf('SYS');
        });
        self.Visible = ko.computed(function () {
            //console.log('data.ColumnName.indexOf(\'SYS\'):', data.ColumnName.indexOf('SYS'));
            return data.ColumnName.indexOf('SYS') >= 0 ? false : true;
        });
    }
    // ---------------------------------------------------------------------------

    function RowViewModel(data, parent) {
        var self = this,
            nbsp = String.fromCharCode(160);

        // observables
        ko.mapping.fromJS(data, {}, self);

        // computeds
        self.HrefDetailsPage = ko.computed(function () {
            return parent.invtype + '/' + data.Id;
        });

        self.selectedItem = ko.observable();
        self.setSelectedItem = function () {
            console.dir(this);
            self.selectedItem(this);
        };
        self.getDetails = function (details) { 
            self.selectedItem(details);
            //console.dir(self.selectedItem);
            return details; // self.selectedItem();
        }
    }
    // ---------------------------------------------------------------------------

    function ViewModel() {
        var self = this;

        // raw values
        self.invtype = "@ViewBag.invtype"; //"Pavement";

        // observables
        self.columns = ko.observableArray();
        self.rows = ko.observableArray();

        // computeds
        self.visibleColumns = ko.computed(function () {
            return ko.utils.arrayFilter(self.columns(), function (column) { 
                return column.isVisible;
            });
        });

        // methods 

        self.load = function () {
            $.when(
            // use two plain $.get() calls to your API resources here
            // the $.post() is required only for the mock-up in jsFiddle
            $.post("/echo/json/", {
                json: JSON.stringify(columnDefs)
            }),
            $.post("/echo/json/", {
                json: JSON.stringify(rowDefs)
            }))
                .then(function (columnResponse, rowResponse) {
                var columnDefs = columnResponse[0],
                    rowDefs = rowResponse[0],
                    columnMapping = {
                        key: function (data) {
                            return ko.utils.unwrapObservable(data.ColumnName);
                        },
                        create: function (options) {
                            return new HeaderViewModel(options.data, self);
                        }
                    },
                    rowMapping = {
                        key: function (data) {
                            return ko.utils.unwrapObservable(data.Id);
                        },
                        create: function (options) {
                            return new RowViewModel(options.data, self);
                        }
                    };

                ko.mapping.fromJS(columnDefs, columnMapping, self.columns);
                ko.mapping.fromJS(rowDefs, rowMapping, self.rows);
            });

            return self;
        };
    }
    // ---------------------------------------------------------------------------

    ko.applyBindings(new ViewModel().load());


      </script>  

//HTML - 用户界面

   <div class="details" data-bind="visible:rows.selectedItem">
     <div data-bind="with: rows.selectedItem">
            details data.......
            <pre data-bind="text: JSON.stringify(ko.toJSON($data))"></pre>
            <input data-bind="value:Id" />

            <!-- TODO dynamicly output label and data from the viewmodel -->

            <b>ID:</b> <span data-bind="text: Id"></span>
            <b>ACX Name:</b> <span data-bind="text:ACX_Name"></span>
            <b>Inv ID:</b> <span data-bind="text:ACX_Name"></span>

      </div>
    </div>
    <div data-bind="visible: rows.selectedItem == null">
        No selection was made
    </div>
    <div id="listPlaceholder"> 
        <table>
        <thead>
            <tr>
                <th>Link</th>
                <!-- ko foreach: $root.visibleColumns -->
                <th data-bind="text: HeaderName, visible: Visible"></th>
                <!-- /ko -->
            </tr>
        </thead>
        <tbody data-bind="foreach: $root.rows">
            <tr data-bind="click: $data.setSelectedItem">
                <td><a href="" data-bind="attr: {href: HrefDetailsPage}">Details</a></td>
                <!-- ko foreach: $root.visibleColumns --> 
                <td data-bind="text: $parent[ColumnName()], visible: Visible"></td>
                <!-- /ko -->
            </tr>
        </tbody>
        </table>

    </div>

使用上面的代码,我正在查看数据 self.setSelectedItem = function () { 控制台.dir(这个); self.selectedItem(this); };

我想在该部分详细输出此数据

沙盒:(http://jsfiddle.net/sigibb/tq55u/)

【问题讨论】:

    标签: knockout.js knockout-mapping-plugin master-detail


    【解决方案1】:

    selectedItem 属性放错了位置,因此将其移至 ViewModel 类。 现在,如果您单击一行,其详细信息将显示在顶部。

    See fiddle

    function ViewModel() {
         var self = this;
         self.selectedItem = ko.observable(null);
    }
    <div data-bind="with: selectedItem">test <pre data-bind="text: JSON.stringify(ko.toJSON($data))"></pre>
        <input data-bind="value:Id" /> <b>ID:</b>  <span data-bind="text: Id"></span>
    </div>
    

    编辑:

    对不起,西加根。当我看到 html 顶部的详细信息 div 时,我认为您只需要所有行的一个详细信息。 我更新了小提琴以获得主视图和详细视图。

    See new Fiddle

    希望对你有帮助。

    【讨论】:

    • 谢谢达米安。您介意解释一下为什么它在 RowViewModel 中不起作用吗?因为我希望每行的值都是唯一的,所以假设我会将单击详细信息转换为多个复选框并显示详细信息...我会在 rowviewmodel 中有 selectedItem 吗?
    猜你喜欢
    • 2013-01-09
    • 2017-09-22
    • 1970-01-01
    • 2013-06-23
    • 2013-03-06
    • 2014-01-17
    • 2013-02-12
    • 2012-07-16
    • 1970-01-01
    相关资源
    最近更新 更多