访问dxDataGrid中的子对象属性

时间:2015-02-04 15:45:55

标签: knockout.js devexpress devextreme

我正在构建一个包含大量数据网格的应用程序(多渠道),而这个问题是我无法在DevExtreme教程和指南中找到解决方案。<登记/> 我使用dxDataGrid方法实施了knockout,这是我的实体:

(function() {
    Application1.playerViewModel = function(data) {
            this.id = ko.observable();
            this.firstname = ko.observable();
            this.lastname = ko.observable();
            this.fullname = ko.observable();
            this.date_of_birth = ko.observable();
            this.country = ko.observable();
            this.team = ko.observable();
            this.teamname = ko.observable();
            this.position = ko.observable();
            if(data)
                this.fromJS(data);
    };

    $.extend(Application1.playerViewModel.prototype, {
        toJS: function () {
            return {
                id: this.id(),
                firstname: this.firstname(),
                lastname: this.lastname(),
                date_of_birth: this.date_of_birth(),
                fullname: this.firstname()+" "+this.lastname,
                country: Application1.db.objectLink("countries", this.country() ? this.country().id(): undefined),
                team: Application1.db.objectLink("teams", this.team() ? this.team().id() : undefined),
                teamname: this.team().name(),
                position: Application1.db.objectLink("positions", this.position() ? this.position().id(): undefined),
            };
        },

        fromJS: function(data) {
            if(data) {
                this.id(data.id);
                this.firstname(data.firstname);
                this.lastname(data.lastname);
                this.fullname(data.firstname + " " + data.lastname);
                this.date_of_birth(data.date_of_birth);
                if(data.country)
                    this.country(new Application1.countryViewModel(data.country));
                if(data.team){
                    this.team(new Application1.teamViewModel(data.team));
                    this.teamname = data.team.name;
                }
                if(data.position)
                    this.position(new Application1.positionViewModel(data.position));
            }
        }
    });
})();

以下是viewModel

Application1.players = function (params, viewInfo) {
    "use strict";

    var shouldReload = false,
        openCreateViewAsRoot = viewInfo.layoutController.name === "split",
        playersDataSource = new DevExpress.data.DataSource({
            store: Application1.db.players,
            map: function (item) {
                return new Application1.playerViewModel(item);
            }
        }),
        dataFieldList =  [
            { dataField: 'firstname', allowGrouping: false },
            { dataField: 'lastname', allowGrouping: false },
            { dataField: 'date_of_birth', sortIndex: 0, sortOrder: 'asc', allowGrouping: false },
            { dataField: 'country', visible: false },
            { dataField: 'team', allowGrouping: true },
            { dataField: 'position', allowGrouping: true },
            { dataField: 'fullname', visible: false, allowGrouping: false}
        ], columnChooser = { enabled: true }, allowColumnReordering = true, sorting = { mode: 'multiple' },
            groupPanel = { visible: true, emptyPanelText: 'Drag a column header here to group grid records' },
            pager = { visible: true },
            paging = { pageSize: 10 },
            editing = {
                editEnabled: true,
                editMode: 'row',
                insertEnabled: true,
                removeEnabled: true
            },
            filterRow = { visible: true },
            searchPanel = { visible: true },
            selection = { mode: 'none' } ;

    function handleplayersModification() {
        shouldReload = true;
    }

    function handleViewShown() {
        if (shouldReload) {
            shouldReload = false;
            dataSource.pageIndex(0);
            dataSource.load();
        }
    }

    function handleViewDisposing() {
        Application1.db.players.off("modified", handleplayersModification);
    }

    function refreshList() {
        dataSource.pageIndex(0);
        dataSource.load();
    }

    Application1.db.players.on("modified", handleplayersModification);

    return {
        refreshList: refreshList,
        viewShown: handleViewShown,
        viewDisposing: handleViewDisposing,
        openCreateViewAsRoot: openCreateViewAsRoot,
        players: playersDataSource,
        dataFieldList: dataFieldList,
        columnChooser: columnChooser,
        allowColumnReordering: allowColumnReordering,
        sorting: sorting,
        groupPanel: groupPanel,
        pager: pager,
        paging: paging,
        editing: editing,
        filterRow: filterRow,
        searchPanel: searchPanel,
        selection: selection
    };
};

HTML:

 <div style="height:800px; margin: 0 auto"
         data-bind="dxDataGrid:{ dataSource:players, columns:dataFieldList, columnChooser:columnChooser, allowColumnReordering:allowColumnReordering, sorting:sorting, groupPanel:groupPanel, pager:pager, paging:paging, editing:editing, filterRow:filterRow, searchPanel:searchPanel, selection:selection }"></div>

结果: enter image description here

我尝试将team.nameposition.name放在配置对象dataFields的{​​{1}}中,但它会返回空白列。

1 个答案:

答案 0 :(得分:3)

通常,您不需要在dxDataGrid数据源中使用Knockout驱动的视图模型,因为dxDataGrid提供了开箱即用的CRUD支持。因此,没有什么能阻止您构建与列模式完全匹配的扁平对象,而不是使用生成的视图模型。

此外,如果您使用的是ODataContext,除非您通过 extend 选项明确指定,否则它不会加载导航属性。有关详细信息,请阅读Associations文档。

您的数据源定义可能如下:

playersDataSource = new DevExpress.data.DataSource({
    store: Application1.db.players,
    map: function (item) {
        return {
            firstname: item.firstname,
            lastname: item.lastname,
            date_of_birth: item.date_of_birth,
            country: item.country.name,
            team: item.team.name,
            position.item.position.name,
            fullname: item.fullname
        };
    },
    expand: ['country', 'team', 'position']
}),

<强>更新 我以前的答案不是最好的,因为如果您以这种方式声明数据源,则不会编辑国家/地区,团队和职位。要支持修改,请从数据源中删除<​​strong>地图方法,然后使用lookup列。在这种情况下,您甚至不需要扩展导航属性,因为它们将通过查找进行扩展。这是一个简短的例子:

playersDataSource = new DevExpress.data.DataSource({
    store: Application1.db.players
}),
columns:[{ 
    dataField: country, 
    lookup: { 
        dataSource: { store: Application1.db.countries }, 
        displayExpr: 'name',
        valueExpr: 'id'
    }
}]