0

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

与其他专家的问题延续的一部分(动态列和行与 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 () { console.dir(this); self.selectedItem(this); };

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

沙箱:(http://jsfiddle.net/sigibb/tq55u/

4

1 回答 1

0

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

见小提琴

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 时,我认为您只需要所有行的一个详细信息。我更新了小提琴以获得主视图和详细视图。

见新的小提琴

我希望它有所帮助。

于 2013-05-04T11:46:34.903 回答