【问题标题】:sencha touch 2: binding associations data to existing storesencha touch 2:将关联数据绑定到现有商店
【发布时间】:2013-05-29 15:24:42
【问题描述】:

我有一个看起来像这样的简单数据模型(下面的实际代码):

model Game:
  fields: id, team_1_id, team_2_id

model GameScore:
  fields: id, game_id, team_1_score, team_2_score, is_final, submission_date

model SpiritScore:
  fields: id, game_id, team_1_score, team_2_score

我想要的似乎很简单。我已经有了批量加载游戏和游戏分数的代码。我手头有一个“游戏”实例,可以调用 gameScores()。我有一家商店,但它是空的。我有代码可以动态加载它,方法是将商店放入模型的 hasMany 定义中。但我真正想要的是将 Game.gameScores() 调用绑定到我现有的 GameScores 商店的某种方式。即使它在下面使用了普通过滤器,这也给了我一个可以绑定并在视图中使用的记录。 (重要提示:数据不是嵌套形式。)

这就引出了我的第二个问题。 Game:GameScores 是 1:many,但我只显示最近的一个(来自实时比分报告)。这里的一般方法是什么?我也可以从 game_id 手动构建过滤器,但我只能将 1 条记录绑定到视图,所以我看不到如何将其他信息带入视图,缺少适当的 hasMany 关系。还有其他方法吗?

任何和所有的建议,包括告诉我 RTFM(带有相关手册的链接)都将不胜感激!上周我一直在这个(公益项目)上大发雷霆。

干杯!

b

Ext.define('TouchMill.model.Game', {
    extend: 'Ext.data.Model',

    config: {
        fields: [ 'id', 'team_1_id', 'team_2_id' ],
        hasMany: {
            model: 'TouchMill.model.GameScore',
            name: 'gameScores',
        },
    },
});

Ext.define('TouchMill.model.GameScore', {
    extend: 'Ext.data.Model',

    config: {
        fields: [ 'id', 'game_id', 'team_1_score', 'team_2_score', 'is_final', 'submission_date', ],
    },
    // belongsTo necessary?  Don't think so unless I want parent func?
});

Ext.define('TouchMill.model.SpiritScore', {
    extend: 'Ext.data.Model',

    config: {
        fields: [ 'id', 'game_id', 'team_1_score', 'team_2_score', ],
    },
},

【问题讨论】:

    标签: extjs touch store has-many


    【解决方案1】:

    我从来没有使用过触摸,所以我在这里谈论的是 Ext4(准确地说是 4.2)......而且,你的模型定义对我来说似乎有点坏了(这与触摸一起工作吗?)。但无论如何,你会得到一般的想法。如果我的代码无法正常工作,请尝试使用 Ext4。

    另外,我了解到您正在一次加载所有乐谱。如果不是这样,我的解决方案将需要调整......

    所以,我的一般推理如下:如果您已将所有分数加载到内存中,那么为什么不使用将分数存储的数据用作为关联生成的存储的数据源的内存代理呢?我试过了,令我惊讶的是,它没有出现任何故障。

    要理解这一点,您需要知道代理是一个独立的数据源,即一个代理可以在多个商店之间毫无问题地共享。另一方面,商店应该绑定到单个视图或任务。例如,如果您将同一个商店绑定到两个不同的网格,那么过滤第一个网格也会影响第二个。

    虽然大多数代理不“包含”它们的数据,但内存代理却可以。这是Ext.data.proxy.Memory#read方法的相关摘录:

    resultSet = operation.resultSet = me.getReader().read(me.data)
    

    所以,足够的理论,这里是概念证明(在fiddle 中测试):

    // I instantiate this proxy myself in order to have a reference available
    var masterScoreProxy = Ext.create('Ext.data.proxy.Memory');
    
    Ext.define('TouchMill.model.GameScore', {
        extend: 'Ext.data.Model',
        fields: [ 'id', 'game_id', 'team_1_score', 'team_2_score', 'is_final', 'submission_date' ],
        // I've used a remote server to ensure this all works even asynchronously
        proxy: {
            // configure your own
        }
    });
    
    Ext.define('TouchMill.model.Game', {
        extend: 'Ext.data.Model'
        ,fields: [ 'id', 'team_1_id', 'team_2_id' ]
        ,hasMany: {
            model: 'TouchMill.model.GameScore'
            ,name: 'gameScores'
            // required in order to avoid Ext autogenerating it as 'touchmill.model.game_id'
            ,foreignKey: 'game_id'
            // needed if we don't want to have to call gameRecord.gameScores().load()
            ,autoLoad: true
    
            // first part of the magic: make the generated store use my own proxy
            ,storeConfig: {
                proxy: masterScoreProxy
            }
        }
    });
    
    // Just mocking a store with two games
    var gameStore = Ext.create('Ext.data.Store', {
        model: 'TouchMill.model.Game'
        ,data: [{id: 1}, {id: 2}]
        ,proxy: 'memory'
    });
    
    // Creating the "master" score store (that will use the model's proxy)
    var scoreStore = Ext.create('Ext.data.Store', {
        model: 'TouchMill.model.GameScore'
    
        // second part's in there
        ,listeners: {
            load: function(store, records, success) {
                if (success) {
                    // 1. replace the data of the generated association stores' proxy
                    // (I must say I'm quite surprised that I didn't had to extract the data of
                    // every records, nor to configure a reader and all for my shared proxy...
                    // But hey, that works!)
                    masterScoreProxy.data = records;
    
                    // 2. update already generated stores
                    // Alternatively, you could call gameRecord.gameScores().load() individually
                    // before each usage of gameRecord.gameStores()
                    gameStore.each(function(record) {
                        var childStore = record.gameScoresStore;
                        if (childStore) {
                            childStore.load();
                        }
                    });
                }
            }
        }
    });
    
    // test first load
    scoreStore.load({
        callback: function(records, operation, success) {
            if (success) {
                // and here's to prove it
                gameStore.each(function(record) {
                    record.gameScores().each(function(score) {
                        console.log('Game ' + record.id + ': ' + JSON.stringify(score.data, undefined, 2));
                    });
                });
    
                testRefreshedData();
            }
        }
    });
    
    function testRefreshedData() {
        // test refreshing
        scoreStore.load({
            callback: function(records, operation, success) {
                if (success) {
                    console.log('--- Scores have changed ---');
                    gameStore.each(function(record) {
                        record.gameScores().each(function(score) {
                            console.log('Game ' + record.id + ': ' + JSON.stringify(score.data, undefined, 2));
                        });
                    });
                }
            }
        });
    }
    

    关于您的其他问题...

    如果 Game:Score 是 1:n,那么 Game:MostRecentScore 是 1:1...所以,我会尝试使用它。

    至于视图,应该总是有一种方法——即使是骇人听闻的——来访问嵌套在您的记录中的数据。方式将取决于您在此处调用的视图...例如,请参阅question

    【讨论】:

    • 哇。这是一个美妙的开始!谢谢!稍后我将尝试一起破解它。不同之处在于,游戏实际上是动态加载的——但只需要不经常刷新,因此同时刷新相关分数很方便。此外,这种缓存概念也适用于其他事物。
    猜你喜欢
    • 1970-01-01
    • 2012-06-17
    • 2014-01-25
    • 1970-01-01
    • 2012-05-29
    • 2013-03-19
    • 2023-04-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多