1

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

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', ],
    },
},
4

1 回答 1

1

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

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

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

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

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

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

所以,足够的理论,这是概念证明(在这个小提琴中测试):

// 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...所以,我会尝试使用它。

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

于 2013-05-30T01:22:28.393 回答