我正在尝试在Sencha Touch中构建一个自定义组件,它将显示两个商店的值。我正在尝试构建从Ext.data.DataView扩展的Ext.us.Cover。由于我是Sencha的初学者,我可以使用一些帮助来完成如何将两个商店绑定到一个视图。
以下是我目前的情况:
/**
* @class Ext.ux.CrossCover
* @extend Ext.DataView
*
* A CrossCover represents two intersecting Cover flows
* @author Abhishek Mukherjee
*/
Ext.define('Ext.ux.CrossCover',{
extend: 'Ext.DataView',
xtype: 'cover',
config:{
/**
* @cfg {Number} selectedIndex The idx from the Store that will be active first. Only one item can be active at a
* time
* @accessor
* @evented
*/
selectedIndex: 0,
/**
* @cfg {String} itemCls
* A css class name to be added to each item element.
*/
itemCls: '',
/**
* @cfg {Boolean} preventSelectionOnItemTap
* Prevent selection when item is tapped. This is false by default.
*/
preventSelectionOnItemTap: false,
/**
* @cfg {Number} angle for cover background items
* This is the angle that not selected items are moved in space.
*/
angle: 75,
/**
* @cfg {Boolean} set to true if you want a flat representation. Defaults to false so the
* coverflow remains 3d.
*/
flat: false,
/**
* @cfg {Boolean} preventOrientationChange
* Prevent attaching refresh method to orientation change event on Ext.Viewport
*/
preventOrientationChange: false,
/**
* @cfg {Ext.data.Store} horizontalStore
* Store containing data for horizontal cover-flow
*/
horizontalStore: '',
//private
baseCls: 'ux-cover',
//private
itemBaseCls: 'ux-cover-item-inner',
//private
scrollable: null,
//private
orientationCls: undefined
},
offset: 0,
horizontalOffset: 0,
//override
initialize: function(){
console.log("Called");
//we need somehow to put the itemCls to the tpl wraper element
this.innerItemCls = this.getItemCls();
if(this.innerItemCls) {
this.setItemCls(this.innerItemCls+'-wrap');
}
this.callParent();
console.log(this.element.type);
this.element.on({
drag: 'onDrag',
dragstart: 'onDragStart',
dragend: 'onDragEnd',
scope: this
});
this.on({
painted: 'onPainted',
itemtap: 'doItemTap',
scope: this
});
if(!this.getPreventOrientationChange()){
//subscribe to orientation change on viewport
Ext.Viewport.on('orientationchange', this.refresh, this);
}
this.setItemTransformation = (this.getFlat())?this.setItemTransformFlat:this.setItemTransform3dVertical;
},
getElementConfig: function(){
console.log("getElementConfig Called");
return {
reference: 'element',
children:[{
reference: 'innerElement',
className: 'ux-cover-scroller'
}]
};
},
applyFlat: function(flat) {
return (Ext.os.is('Android')? true : flat);
},
updateOrientationCls: function(newOrientation, oldOrientation) {
var baseCls = this.getBaseCls();
if(this.element && newOrientation != oldOrientation) {
this.element.removeCls(baseCls+'-'+oldOrientation);
this.element.addCls(baseCls+'-'+newOrientation);
}
},
applyItemTpl: function(config){
console.log("applyItemTpl Called");
if(Ext.isArray(config)){
config = config.join("");
}
return new Ext.XTemplate('<div class="' + this.getItemBaseCls() + ' ' + this.getItemCls() + ' ">'+config+'</div>');
},
onPainted: function(){
this.refresh();
},
//private
getTargetEl: function(){
console.log("getTargetEl Called");
return this.innerElement;
},
onDragStart: function(){
console.log("onDragStart Called");
this.getTargetEl().dom.style.webkitTransitionDuration = "0s";
},
onDrag: function(e){
console.log("onDrag Called");
var curr = this.getOffset(),
offset,
ln = this.getViewItems().length,
selectedIndex,
delta = (e.deltaY - e.previousDeltaY);
//slow down on border conditions
selectedIndex = this.getSelectedIndex();
if ((selectedIndex === 0 && e.deltaY > 0) || (selectedIndex === ln - 1 && e.deltaY < 0)) {
delta *= 0.5;
}
offset = curr + delta;
this.setOffset(offset, true);
},
onDragEnd: function(){
console.log("onDragEnd Called");
var idx = this.getSelectedIndex(),
y = - (idx * this.gap);
this.getTargetEl().dom.style.webkitTransitionDuration = "0.4s";
//this.setOffset(x);
this.applySelectedIndex(idx);
},
doItemTap: function(cover, index, item, evt){
if(!this.getPreventSelectionOnItemTap() && this.getSelectedIndex() !== index){
this.setSelectedIndex(index);
}
},
getSelectedIndex: function(){
console.log("getSelectedIndex Called");
var idx, ln;
if(this.isRendered()){
ln = this.getViewItems().length;
idx = - Math.round(this.getOffset() / this.gap);
this.selectedIndex = Math.min(Math.max(idx, 0), ln - 1);
}
return this.selectedIndex;
},
applySelectedIndex: function(idx){
console.log("applySelectedINdex Called");
if(this.isRendered()){
this.updateOffsetToIdx(idx);
this.selectWithEvent(this.getStore().getAt(idx));
}else{
this.selectedIndex = idx;
}
// apply horizontal index
this.applySelectedHorizontalIndex(idx);
},
applySelectedHorizontalIndex: function(idx){
console.log("applySelectedHorizontalIndex Called");
if(this.isRendered()){
this.updateHorizontalOffsetToIdx(idx);
this.selectWithEvent(this.getHorizontalStore().data.items[idx]);
}else{
this.selectedIndex = idx;
}
},
updateOffsetToIdx: function(idx){
console.log("updateOffsetToIdx Called");
var ln = this.getViewItems().length,
offset;
idx = Math.min(Math.max(idx, 0), ln - 1);
offset= -(idx * this.gap);
this.setOffset(offset);
},
updateHorizontalOffsetToIdx: function(idx){
console.log("updateHorizontalOffsetToIdx Called");
var ln = this.getHorizontalStore().data.items.length,
offset;
// console.log("Number of horizontal items is ")
idx = Math.min(Math.max(idx, 0), ln - 1);
offset= -(idx * this.gap);
this.setHorizontalOffset(offset);
},
setOffset: function(offset){
console.log("setOffset Called");
// Set offset for the vertical cover
var items = this.getViewItems(),
idx = 0,
l = items.length,
item;
this.offset = offset;
// Changing the translation to Y-axis
this.getTargetEl().dom.style.webkitTransform = "translate3d( 0," + offset + "px, 0)";
for(;idx<l;idx++){
item = Ext.get(items[idx]);
this.setItemTransformation(item, idx, offset);
}
},
setHorizontalOffset: function(offset){
console.log("setHorizontalOffset Called");
// Set offset for the horizontal cover
var hitems = this.getHorizontalStore().data.items,
hidx = 0,
hl = hitems.length,
hitem;
console.log("horizontal store items :"+hl);
this.horizontalOffset = offset;
// Changing the translation to X-axis
this.getTargetEl().dom.style.webkitTransform = "translate3d( " + offset + "px, 0, 0)";
for(;hidx<hl;hidx++){
hitem = document.createElement("div");
var newContent = document.createTextNode(hitems[hidx].data.preferredName);
hitem.appendChild(newContent);
console.log("hitem is"+hitem);
this.setItemTransform3dHorizontal(hitem, hidx, offset);
}
},
getOffset: function(){
console.log("getOffset Called");
return this.offset;
},
getHorizontalOffset: function(){
console.log(" getHorizontaloffset Called");
return this.horizontalOffset;
},
getBaseItemBox: function(containerBox){
console.log("getBaseItemBox Called");
var cH = containerBox.height,
cW = containerBox.width,
sizeFactor = (cW > cH) ? 0.68 : 0.52,
h, w;
h = w = Math.min(containerBox.width, containerBox.height) * sizeFactor;
return {
top: (containerBox.height - w) / 2 ,
height: h * 1.5,
width: w,
left: (containerBox.width - w) / 2
};
},
setBoundaries: function(itemBox){
console.log("setBoundaries Called");
var w = itemBox.width;
if(this.getFlat()){
this.gap = w * 1.1;
this.threshold = this.gap / 3;
this.delta = w * 0.2;
} else {
this.gap = w / 3;
this.threshold = this.gap / 2;
this.delta = w * 0.4;
}
},
setItemTransformation: Ext.emptyFn,
setItemTransform3dVertical: function(item, idx, offset){
console.log("type of item is:"+ item.type);
console.log("Called setItemTransform3dVertical"+offset);
var x = idx * this.gap,
ix = x + offset,
transf = "";
if(ix < this.threshold && ix >= - this.threshold){
// Changing the translation to Y-axis
transf = "translate3d( 0,"+x+"px, 150px)";
this.selectedIndex = idx;
}else if(ix > 0){
// Changing the rotation to x-axis
transf = "translate3d( 0 ,"+(x+this.delta)+"px, 0 ) rotateX(-"+this.getAngle()+"deg)";
}else{
// Changing the rotation to x-axis
transf = "translate3d( 0, "+(x-this.delta)+"px, 0 ) rotateX("+this.getAngle()+"deg)";
}
item.dom.style.webkitTransform = transf;
},
setItemTransform3dHorizontal: function(item, idx, offset){
console.log("Called setItemTransform3dHorizontal"+offset);
console.log("item receieved::"+item + " idx is "+idx+" offset is "+offset);
var x = idx * this.gap,
ix = x + offset,
transf = "";
if(ix < this.threshold && ix >= - this.threshold){
// Changing the translation to X-axis
transf = "translate3d( "+x+"px, 0, 150px)";
this.selectedIndex = idx;
}else if(ix > 0){
// Changing the rotation to Y-axis
transf = "translate3d( "+(x+this.delta)+"px, 0 , 0 ) rotateY(-"+this.getAngle()+"deg)";
}else{
// Changing the rotation to Y-axis
transf = "translate3d( "+(x-this.delta)+"px, 0, 0 ) rotateY("+this.getAngle()+"deg)";
}
item.style.webkitTransform = transf;
},
setItemTransformFlat: function(item, idx, offset){
var x = idx * this.gap,
ix = x + offset,
transf = "";
if(ix < this.threshold && ix >= - this.threshold){
// Changing the translation to Y-axis
transf = "translate3d( 0, "+x+"px, 150px)";
this.selectedIndex = idx;
}else if(ix > 0){
transf = "translate3d("+(x+this.delta)+"px, 0, 0)";
}else{
transf = "translate3d("+(x-this.delta)+"px, 0, 0)";
}
item.dom.style.webkitTransform = transf;
},
doRefresh: function(me){
console.log("doRefresh Called");
var container = me.container,
items, idx = 0, l,
orientation = Ext.Viewport.getOrientation();
this.setOrientationCls(orientation);
this.callParent([me]);
items = container.getViewItems();
l = items.length;
this.itemBox = this.getBaseItemBox(this.element.getBox());
this.setBoundaries(this.itemBox);
for(;idx<l;idx++){
this.resizeItem(items[idx]);
}
this.setSelectedIndex(this.selectedIndex);
// Refresh the horizontal cover flow
this.refreshHorizontalCover();
},
refreshHorizontalCover: function(){
console.log("refreshHorizontalCover Called");
//var container = me.container,
var hitems, hidx = 0, hl;
// orientation = Ext.Viewport.getOrientation();
//this.setOrientationCls(orientation);
//this.callParent([me]);
hitems = this.getHorizontalStore().data.items;
hl = hitems.length;
this.itemBox = this.getBaseItemBox(this.element.getBox());
this.setBoundaries(this.itemBox);
for(;hidx<hl;hidx++){
var item = document.createElement("div");
var newContent = document.createTextNode(hitems[hidx].data.preferredName);
item.appendChild(newContent); //add the text node to the newly created div.
this.resizeHorizontalItem(item);
}
this.setSelectedIndex(this.selectedIndex);
},
resizeItem: function(element){
console.log("resizeItem Called");
var itemBox = this.itemBox,
item = Ext.get(element);
item.setBox(itemBox);
/**
itemBox has an extra long in height to avoid reflection opacity over other items
I need to create a wrapper element with same bg to avoid that issue.
*/
item.down('.'+this.getItemBaseCls()).setBox({height: itemBox.height/1.5, width: itemBox.width});
},
resizeHorizontalItem: function(element){
console.log("resizeHorizontalItem Called");
var itemBox = this.itemBox,
item = Ext.get(element);
item.setBox(itemBox);
/**
itemBox has an extra long in height to avoid reflection opacity over other items
I need to create a wrapper element with same bg to avoid that issue.
*/
//item.down('.'+this.getItemBaseCls()).setBox({height: itemBox.height/1.5, width: itemBox.width});
},
//override
onStoreUpdate: function(store, record, newIndex, oldIndex) {
var me = this,
container = me.container,
item;
oldIndex = (typeof oldIndex === 'undefined') ? newIndex : oldIndex;
if (oldIndex !== newIndex) {
container.moveItemsToCache(oldIndex, oldIndex);
container.moveItemsFromCache([record]);
}
else {
item = container.getViewItems()[newIndex];
// Bypassing setter because sometimes we pass the same record (different data)
container.updateListItem(record, item);
me.resizeItem(item);
}
}
});
这里的想法是有两个覆盖流,一个水平,另一个垂直在中间相交。我可以显示一个封面流程,但另一个封面流程没有显示(或者不在视图中)。因为对于一个封面我可以使用DataView中的属性,显示第一个比第二个更容易。我可以帮一些关于如何显示第二个的建议。
我将不胜感激任何帮助。非常感谢你的时间。
答案 0 :(得分:0)
Ext中的数据视图绑定到一个存储。我认为更少的编码是采用两个视图并将它们放在布局中。
答案 1 :(得分:0)
我通过将两个单独的视图叠加在彼此之上并在拖动在特定方向上时将事件从顶视图传递到基础视图来解决它。