Knockout.js 访问dxDataGrid中的子对象属性
我正在构建一个包含大量数据网格的应用程序(多通道),但我无法在Knockout.js 访问dxDataGrid中的子对象属性,knockout.js,devexpress,devextreme,Knockout.js,Devexpress,Devextreme,我正在构建一个包含大量数据网格的应用程序(多通道),但我无法在DevExtreme教程和指南中找到解决方案。 我用knockout方法实现了一个dxDataGrid,下面是我的实体: (function() { Application1.playerViewModel = function(data) { this.id = ko.observable(); this.firstname = ko.observable();
DevExtreme
教程和指南中找到解决方案。我用
knockout
方法实现了一个dxDataGrid
,下面是我的实体:(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));
}
}
});
})();
以下是视图模型:
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:
结果是:
我尝试将
team.name
和position.name
放在配置对象dataFieldList
的数据字段中,但它返回空列。通常,您不需要在dxDataGrid数据源中使用敲除驱动的视图模型,因为dxDataGrid提供了开箱即用的CRUD支持。因此,没有什么可以阻止您构建与列模式完全匹配的平面对象,而不是使用生成的视图模型
此外,如果您正在使用ODataContext,它将不会加载导航属性,除非您通过extend选项明确指定此属性。请阅读文档以了解详细信息
您的数据源定义可能如下所示:
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']
}),
更新
我之前的回答不是最好的,因为如果您以这种方式声明数据源,您将不会编辑国家、团队和职位。要支持编辑,请从数据源中删除map方法并使用列。在这种情况下,甚至不需要展开导航属性,因为它们将通过查找展开。下面是一个简短的例子:
playersDataSource = new DevExpress.data.DataSource({
store: Application1.db.players
}),
columns:[{
dataField: country,
lookup: {
dataSource: { store: Application1.db.countries },
displayExpr: 'name',
valueExpr: 'id'
}
}]
感谢Tanner的评论,但不幸的是,team().name和team().name()不起作用,两者都返回:我认为它们在本例中返回未定义。感谢天王星,我遵循了您的第二个解决方案,结果很接近,但它没有在每行显示团队名称,结果如下:和columns对象:(我从数据源中删除了映射属性)displayExpr和valueExpr选项用于引用数据源项字段。团队项是否具有相应的字段(名称和id)?如果否,则更改displayExpr和valueExpr选项以引用现有字段。是的,它与position相同,团队具有id和name属性。这是团队视图模型:我只能假设玩家具有单独的团队id字段,并且您需要将dataField列选项设置为“团队”,而不是“团队”。如果您添加地图,则连接到数据源,您可以将断点插入此函数,并在调试器中查看项具有哪些字段。您是对的。播放器具有字段团队id,但当我将该字段放入dataField列并将“id”放入valueExpr字段时,它不起作用: