如何将两个商店绑定到Sencha中的一个视图?

时间:2014-09-15 12:48:06

标签: javascript extjs sencha-touch coverflow

我正在尝试在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中的属性,显示第一个比第二个更容易。我可以帮一些关于如何显示第二个的建议。

我将不胜感激任何帮助。非常感谢你的时间。

2 个答案:

答案 0 :(得分:0)

Ext中的数据视图绑定到一个存储。我认为更少的编码是采用两个视图并将它们放在布局中。

答案 1 :(得分:0)

我通过将两个单独的视图叠加在彼此之上并在拖动在特定方向上时将事件从顶视图传递到基础视图来解决它。