Sencha Touch 2:使用多个商店填充一个DataView

时间:2014-01-17 10:39:07

标签: javascript extjs model-view-controller touch store

我意识到这可能听起来很愚蠢,所以希望这并不会让人觉得太愚蠢。我想使用多个商店来填充一个DataView,或者我可以应用itemTpl的其他项目。我有一个基本的想法,我想要实现:

  • 我有一个用户和物品商店,用户可以购买物品。
  • 每个用户都有一个相关的余额,用于指示他们可以购买的商品。

我希望能够提供可以购买的商品列表(无论用户的帐户中是否有足够的资金)。用户无法承受的任何项目都应该显示为灰色(但仍然可见)。

从上面的图片中可以看出,第一个用户可以看到所有项目没有任何灰色(因为他们有足够的余额),但是第二个用户没有足够的钱购买盔甲。有没有办法从两个独立的商店(ItemStore和UserStore)中获取信息以列出所有项目,但灰显用户没有足够的项目。

以下是我的代码:

(DataView)ItemSelectionScreen:

Ext.define("touchstore.view.purchase.ItemSelectionScreen", {
    extend: 'Ext.dataview.DataView',
    xtype: 'item-selection',

    config: {
        store: 'ItemStore',
        itemTpl: new Ext.XTemplate(
            '<tpl for=".">',
                '<div class="item {canAfford}">', //canAfford should be that the users balance is greater than the price of the item
                    '<h1>{itemName}</h1>',
                    '<span>{description}</span><br />',
                    '<div class="cost"><strong>Cost: {cost}</strong></div>',
                '</div>',
            '</tpl>')
    }
});

ItemModel:

Ext.define('touchstore.model.ItemModel', {    
    extend: 'Ext.data.Model',

    config: {
        fields: [
            { name: 'itemName', type: 'string' },
            { name: 'description', type: 'string' },
            { name: 'cost', type: 'int' }
        ]
    }
});

ItemStore:

Ext.define("touchstore.store.ItemStore", {
    extend: 'Ext.data.Store',

    config: {
        model: 'touchstore.model.ItemModel',
        data: [
            { itemName: 'Sword', description: 'Battle your enemies fiercely with this beautiful, yet deadly sword.', cost: 500 },
            { itemName: 'Armour', description: 'Defend yourself from attacks with this beautifully crafted piece of armour.', cost: 1400 },
            { itemName: 'Leather Boots', description: 'Run faster with these lightweight yet stylish boots.', cost: 400 }
        ]
    }
});

的usermodel:

Ext.define("touchstore.model.UserModel", {
    extend: 'Ext.data.Model',

    config: {
        fields: [
            { name: 'username', type: 'string' },
            { name: 'balance', type: 'int' }
        ]
    }
});

UserStore:

Ext.define("touchstore.store.UserStore", {
    extend: 'Ext.data.Store',

    config: {
        model: 'touchstore.model.UserModel',
        data: [
            { username: 'steve.smith', balance: 2000 },
            { username: 'robert.junior', balance: 500 }
        ]
    }
});

2 个答案:

答案 0 :(得分:0)

假设一次只有一个用户处于活动状态,您不需要创建另一个商店,您可以显示ItemStore中的所有项目,只需根据当前活动用户和商品价格计算{canAfford}。

您可以使用XTemplate的最后一个参数来传递一个可以计算canAfford的方法的对象。粗略地说:

new Ext.XTemplate(
        '<tpl for=".">',
            '<div class="item {[this.canAfford(values)]}">', //canAfford should be that the users balance is greater than the price of the item
                '<h1>{itemName}</h1>',
                '<span>{description}</span><br />',
                '<div class="cost"><strong>Cost: {cost}</strong></div>',
            '</div>',
        '</tpl>',
        {
            canAfford: function(item) {
                return item.get('cost') <= CURRENT_USER.get('balance') 
                    ? 'CLASS-FOR-CAN-AFFORD' : 'CLASS-FOR-CANNOT-AFFORD';
            }
        })

CURRENT_USER是对系统上当前活动用户的引用。通常,这将来自登录子系统。假设您实现了一个带有getActiveUser方法的LoginController,该方法返回当前记录的用户,它可能是这样的(Ext JS):

touchstore.getApplication().getController('LoginController').getActiveUser()

如果使用Sencha Touch,它将是:

touchstore.app.getController('LoginController').getActiveUser()

修改

另一种选择是使用视图中的配置来传递当前用户。您认为的相关变化:

Ext.define("touchstore.view.purchase.ItemSelectionScreen", {
    ...

    config: {
        currentUser: null,

        // Empty template so there will be no errors. 
        // The real template is configured in the initialize method.
        itemTpl: '',
        ...
    },
    ...
    updateCurrentUser: function(newUser) {
       this.refresh();
    },

    // Setup the template in the initialize method. The initConfig is
    // probably better for this, but I could not test it.
    initialize: function() {
        var me = this;
        // The template is configured here so it can access me.getCurrentUser().
        me.setItemTpl(new Ext.XTemplate(...));
        me.callParent(arguments);
    }
});

如果您的控制器没有实例化视图,它可以在视图的initialize事件和/或当前用户更改时初始化此值。

答案 1 :(得分:0)

我不确定是否有效,但请尝试一下并告诉我。

Ext.define("touchstore.view.purchase.ItemSelectionScreen", {
extend: 'Ext.dataview.DataView',
xtype: 'item-selection',

config: {
    store: [ItemStore,UserStore],
    itemTpl: new Ext.XTemplate(
        '<tpl for=".">',
            '<tpl if="{balance} &gt; {cost}"',
                '<div>',
                    '<h1>{itemName}</h1>',
                    '<span>{description}</span><br />',
                    '<div class="cost"><strong>Cost: {cost}</strong></div>',
                '</div>',
             '</tpl>',
        '</tpl>')
}
});