使用 DataView 示例创建照片库
Using the DataView Example to create a photo gallery
我正在使用 ExtJS 构建 Web 应用程序。在我的网络应用程序中,用户可以将照片上传到服务器目录。此外,我还将文件路径与用户 ID 一起保存到数据库 table,以便我知道某张照片是谁的照片。当然,我也希望他们能够看到它。我可以根据登录用户正确获取数据库行。但是,我现在遇到的困难是向用户展示他或她的照片。
网上搜索了一下,我saw this example是Sencha提供的。查看代码后,它似乎很简单,可以集成到我现有的应用程序中。
检查提供的 data-view.js file 后,我发现它使用了 ext/src/ux/
子目录中已经提供的 2 个插件,因此我认为添加它们和我的 app.js 文件没有任何意义看起来像这样:
requires: [
'Ext.Loader',
'Ext.layout.container.Absolute',
'Ext.layout.container.Column',
'Ext.grid.*',
'Ext.ux.DataView.DragSelector',
'Ext.ux.DataView.LabelEditor'
],
现在,我也有了自己的模特,也有了自己的店铺。
我的模型看起来像:
Ext.define('app.model.ciGallery', {
extend: 'Ext.data.Model',
requires: [
'Ext.data.Field'
],
fields: [
{
name: 'image_path'
},
{
name: 'description'
},
{
name: 'upload_date'
},
{
name: 'upload_time'
}
]
});
而且我的商店看起来像一个用于在数据库上进行 CRUD 的标准商店。
现在,为了创建相册示例,我所做的是获取我希望相册出现的面板,并为其 afterrender
属性 创建一个函数。在渲染函数之后,我基本上做的是从 Ext.create(....
开始复制粘贴整个示例
看起来像这样:
var store = Ext.getStore("ciGallery");
Ext.create('Ext.Panel', {
id: 'images-view',
frame: true,
collapsible: true,
width: 200,
renderTo: 'dataview-example',
title: 'Simple DataView (0 items selected)',
items: Ext.create('Ext.view.View', {
store: store,
tpl: [
'<tpl for=".">',
'<div class="thumb-wrap" id="{name}">',
'<div class="thumb"><img src="{url}" title="{name}"></div>',
'<span class="x-editable">{shortName}</span></div>',
'</tpl>',
'<div class="x-clear"></div>'
],
multiSelect: true,
height: 310,
trackOver: true,
overItemCls: 'x-item-over',
itemSelector: 'div.thumb-wrap',
emptyText: 'No images to display',
plugins: [
Ext.create('Ext.ux.DataView.DragSelector', {}),
Ext.create('Ext.ux.DataView.LabelEditor', {dataIndex: 'name'})
],
prepareData: function(data) {
Ext.apply(data, {
shortName: Ext.util.Format.ellipsis(data.image_path, 15),
sizeString: Ext.util.Format.fileSize(data.upload_date),
dateString: Ext.util.Format.date(data.upload_time)
});
return data;
},
listeners: {
selectionchange: function(dv, nodes ){
var l = nodes.length,
s = l !== 1 ? 's' : '';
this.up('panel').setTitle('Simple DataView (' + l + ' item' + s + ' selected)');
}
}
})
});
其中ciGallery
是我的店铺,dataview-example
是父面板的id
属性,还有调整prepareData
功能匹配我使用的模型的属性。
但是,当我 运行 我的应用程序转到那个面板时,似乎没有任何东西正确呈现,因为我什么都没有看到,甚至连一个空白面板都没有。
我认为要使其正常工作,需要在 callParent 初始化您的 class.
后在 initComponent 方法中创建嵌入式 DataView
因为我经常使用这种类型的视图,所以我创建了一个基础 class 'DataPanel' 来处理大部分设置,然后在需要时从中派生,只传递特定于模板的详细信息。
这是我实际实现的示例代码。
1) 创建一个名为 'YourNamespace.view.DataPanel.js' 的单独包含文件,其中包含以下代码:
Ext.define('YourNamespace.view.DataPanel', {
extend: 'Ext.panel.Panel'
, alias: 'widget.dataPanel'
, title: ''
, initTitle: ''
, appendRecordToTitle: true
, emptyText: undefined
, itemSelector: ''
, layout: 'fit'
, store: ''
, tpl: ''
, autoWidth: true
, overflowY: 'auto'
, initComponent: function () {
this.callParent(arguments);
this.initTitle = this.title;
var dataView = new Ext.DataView({
emptyText: this.emptyText ? this.emptyText : 'No Items Available.'
, title: this.initTitle
, itemSelector: this.itemSelector
, loadMask: false
, overItemCls: 'x-view-over'
, store: this.store
, tpl: this.tpl
, style: 'padding: 5px'
, width: '100%'
, listeners: {
selectionchange: function(dataview, selection) {
this.up().fireEvent('selectionchange', dataview, selection);
}
}
});
this.add(dataView);
}
, refreshTitle: function (recordTitle) {
if (this.appendRecordToTitle) {
this.setTitle(this.initTitle + ' ' + recordTitle);
}
}
, reset: function() {
}
});
2) 这是一个示例,展示了这个基数的用法 class:
Ext.define('YourNamespace.view.EmployeePhotoPanel', {
extend: 'YourNamespace.view.DataPanel'
, alias: 'widget.employeeSearchResultsPanel'
, minHeight: 600
, itemSelector: 'div.employee'
, store: Ext.create('YourNamespace.store.Employees')
, title: 'Search Results'
, tpl: new Ext.XTemplate(
'<tpl for=".">'
, '<div class="employee">'
, '<img src="/employee/photo?id={employeeNumber}&scale=thumbnail")">'
, '<div class="displayLabel">{displayName:ellipsis(20)}</div>'
, '</div>'
, '</tpl>'
)
, load: function(searchCriteria) {
this.store.load({
params: {
'$filter': searchCriteria
}
, scope: this
})
}
}
);
3) 此示例的模型可能如下所示:
Ext.define('YourNamespace.model.Employee', {
extend: 'Ext.data.Model'
, requires: ['Ext.data.proxy.Rest']
, idProperty: 'employeeNumber'
, fields: [
'employeeNumber', 'displayName'
]
, proxy: {
type: 'rest'
, url: '/employee/record/summary'
}
});
4)店面简单:
Ext.define('YourNamespace.store.Employees', {
extend: 'Ext.data.Store'
, model: 'YourNamespace.model.Employee'
});
5) .css 使其看起来正确:
.employee {
background-color: #F7F7F9;
text-align: center;
vertical-align: bottom;
border: 1px outset #D0D0D0;
padding: 4px;
margin: 2px;
float: left;
display: inherit;
overflow: hidden;
font: normal .8em Arial;
height: 130px;
width: 108px;
}
.employee .displayLabel {
white-space: nowrap;
overflow: hidden;
color: #000000;
}
.employee:hover{
border:1px solid red;
}
6) 在你的控制器中的某个地方你会想要调用你的存储加载方法。该调用应使用信息自动填充您的 DataView。此示例模板有一个嵌入的 html img 标签,它使 restful 回调到服务器以获取每个存储记录到 return 构成图像文件的字节。如果你有静态图像,请修改模板以直接指向图像 url(甚至可能 returning 模型记录中的 url)。
希望对您有所帮助!
好的。这就是我所做的。 View 和 Panel 组件在 Sencha Architect 中很容易获得。我只是将它们添加到我希望画廊所在的面板上,然后设置尽可能多的属性,从示例到组件。我认为我唯一没有使用的是示例中 View 的 renderTo
属性。
现在,当您制作视图时,您必须调整 tpl
代码以及 prepareData
函数以匹配您的商店使用的模型。这是我对 tpl
:
所做的
tpl: [
'<tpl for=".">',
'<div class="thumb"><img src="{image_path}"></div>',
'</tpl>',
'<div class="x-clear"></div>',
''
]
我使用了一个简单的图片库,与示例显示的相反(它有文件名)。为此,我只是删除了其他 div
和 span
对象。
我正在使用 ExtJS 构建 Web 应用程序。在我的网络应用程序中,用户可以将照片上传到服务器目录。此外,我还将文件路径与用户 ID 一起保存到数据库 table,以便我知道某张照片是谁的照片。当然,我也希望他们能够看到它。我可以根据登录用户正确获取数据库行。但是,我现在遇到的困难是向用户展示他或她的照片。
网上搜索了一下,我saw this example是Sencha提供的。查看代码后,它似乎很简单,可以集成到我现有的应用程序中。
检查提供的 data-view.js file 后,我发现它使用了 ext/src/ux/
子目录中已经提供的 2 个插件,因此我认为添加它们和我的 app.js 文件没有任何意义看起来像这样:
requires: [
'Ext.Loader',
'Ext.layout.container.Absolute',
'Ext.layout.container.Column',
'Ext.grid.*',
'Ext.ux.DataView.DragSelector',
'Ext.ux.DataView.LabelEditor'
],
现在,我也有了自己的模特,也有了自己的店铺。
我的模型看起来像:
Ext.define('app.model.ciGallery', {
extend: 'Ext.data.Model',
requires: [
'Ext.data.Field'
],
fields: [
{
name: 'image_path'
},
{
name: 'description'
},
{
name: 'upload_date'
},
{
name: 'upload_time'
}
]
});
而且我的商店看起来像一个用于在数据库上进行 CRUD 的标准商店。
现在,为了创建相册示例,我所做的是获取我希望相册出现的面板,并为其 afterrender
属性 创建一个函数。在渲染函数之后,我基本上做的是从 Ext.create(....
看起来像这样:
var store = Ext.getStore("ciGallery");
Ext.create('Ext.Panel', {
id: 'images-view',
frame: true,
collapsible: true,
width: 200,
renderTo: 'dataview-example',
title: 'Simple DataView (0 items selected)',
items: Ext.create('Ext.view.View', {
store: store,
tpl: [
'<tpl for=".">',
'<div class="thumb-wrap" id="{name}">',
'<div class="thumb"><img src="{url}" title="{name}"></div>',
'<span class="x-editable">{shortName}</span></div>',
'</tpl>',
'<div class="x-clear"></div>'
],
multiSelect: true,
height: 310,
trackOver: true,
overItemCls: 'x-item-over',
itemSelector: 'div.thumb-wrap',
emptyText: 'No images to display',
plugins: [
Ext.create('Ext.ux.DataView.DragSelector', {}),
Ext.create('Ext.ux.DataView.LabelEditor', {dataIndex: 'name'})
],
prepareData: function(data) {
Ext.apply(data, {
shortName: Ext.util.Format.ellipsis(data.image_path, 15),
sizeString: Ext.util.Format.fileSize(data.upload_date),
dateString: Ext.util.Format.date(data.upload_time)
});
return data;
},
listeners: {
selectionchange: function(dv, nodes ){
var l = nodes.length,
s = l !== 1 ? 's' : '';
this.up('panel').setTitle('Simple DataView (' + l + ' item' + s + ' selected)');
}
}
})
});
其中ciGallery
是我的店铺,dataview-example
是父面板的id
属性,还有调整prepareData
功能匹配我使用的模型的属性。
但是,当我 运行 我的应用程序转到那个面板时,似乎没有任何东西正确呈现,因为我什么都没有看到,甚至连一个空白面板都没有。
我认为要使其正常工作,需要在 callParent 初始化您的 class.
后在 initComponent 方法中创建嵌入式 DataView因为我经常使用这种类型的视图,所以我创建了一个基础 class 'DataPanel' 来处理大部分设置,然后在需要时从中派生,只传递特定于模板的详细信息。
这是我实际实现的示例代码。
1) 创建一个名为 'YourNamespace.view.DataPanel.js' 的单独包含文件,其中包含以下代码:
Ext.define('YourNamespace.view.DataPanel', {
extend: 'Ext.panel.Panel'
, alias: 'widget.dataPanel'
, title: ''
, initTitle: ''
, appendRecordToTitle: true
, emptyText: undefined
, itemSelector: ''
, layout: 'fit'
, store: ''
, tpl: ''
, autoWidth: true
, overflowY: 'auto'
, initComponent: function () {
this.callParent(arguments);
this.initTitle = this.title;
var dataView = new Ext.DataView({
emptyText: this.emptyText ? this.emptyText : 'No Items Available.'
, title: this.initTitle
, itemSelector: this.itemSelector
, loadMask: false
, overItemCls: 'x-view-over'
, store: this.store
, tpl: this.tpl
, style: 'padding: 5px'
, width: '100%'
, listeners: {
selectionchange: function(dataview, selection) {
this.up().fireEvent('selectionchange', dataview, selection);
}
}
});
this.add(dataView);
}
, refreshTitle: function (recordTitle) {
if (this.appendRecordToTitle) {
this.setTitle(this.initTitle + ' ' + recordTitle);
}
}
, reset: function() {
}
});
2) 这是一个示例,展示了这个基数的用法 class:
Ext.define('YourNamespace.view.EmployeePhotoPanel', {
extend: 'YourNamespace.view.DataPanel'
, alias: 'widget.employeeSearchResultsPanel'
, minHeight: 600
, itemSelector: 'div.employee'
, store: Ext.create('YourNamespace.store.Employees')
, title: 'Search Results'
, tpl: new Ext.XTemplate(
'<tpl for=".">'
, '<div class="employee">'
, '<img src="/employee/photo?id={employeeNumber}&scale=thumbnail")">'
, '<div class="displayLabel">{displayName:ellipsis(20)}</div>'
, '</div>'
, '</tpl>'
)
, load: function(searchCriteria) {
this.store.load({
params: {
'$filter': searchCriteria
}
, scope: this
})
}
}
);
3) 此示例的模型可能如下所示:
Ext.define('YourNamespace.model.Employee', {
extend: 'Ext.data.Model'
, requires: ['Ext.data.proxy.Rest']
, idProperty: 'employeeNumber'
, fields: [
'employeeNumber', 'displayName'
]
, proxy: {
type: 'rest'
, url: '/employee/record/summary'
}
});
4)店面简单:
Ext.define('YourNamespace.store.Employees', {
extend: 'Ext.data.Store'
, model: 'YourNamespace.model.Employee'
});
5) .css 使其看起来正确:
.employee {
background-color: #F7F7F9;
text-align: center;
vertical-align: bottom;
border: 1px outset #D0D0D0;
padding: 4px;
margin: 2px;
float: left;
display: inherit;
overflow: hidden;
font: normal .8em Arial;
height: 130px;
width: 108px;
}
.employee .displayLabel {
white-space: nowrap;
overflow: hidden;
color: #000000;
}
.employee:hover{
border:1px solid red;
}
6) 在你的控制器中的某个地方你会想要调用你的存储加载方法。该调用应使用信息自动填充您的 DataView。此示例模板有一个嵌入的 html img 标签,它使 restful 回调到服务器以获取每个存储记录到 return 构成图像文件的字节。如果你有静态图像,请修改模板以直接指向图像 url(甚至可能 returning 模型记录中的 url)。
希望对您有所帮助!
好的。这就是我所做的。 View 和 Panel 组件在 Sencha Architect 中很容易获得。我只是将它们添加到我希望画廊所在的面板上,然后设置尽可能多的属性,从示例到组件。我认为我唯一没有使用的是示例中 View 的 renderTo
属性。
现在,当您制作视图时,您必须调整 tpl
代码以及 prepareData
函数以匹配您的商店使用的模型。这是我对 tpl
:
tpl: [
'<tpl for=".">',
'<div class="thumb"><img src="{image_path}"></div>',
'</tpl>',
'<div class="x-clear"></div>',
''
]
我使用了一个简单的图片库,与示例显示的相反(它有文件名)。为此,我只是删除了其他 div
和 span
对象。