【问题标题】:Accessing a store from another store - Sencha Touch从其他商店访问商店 - Sencha Touch
【发布时间】:2013-12-13 13:50:02
【问题描述】:

我正在尝试创建一个商店并在内部访问另一个商店的数据以构建代理 url。

类似这样的:

Ext.define('MyApp.store.Post',{
extend:'Ext.data.Store', 
config: {
    model: 'MyApp.model.Post',
    proxy: {
        type: 'ajax',
        url: 'http://mywebsite.com/get?userid=' + Ext.getStore('UserData').getAt(0).data.userid,
        reader: {
            type: 'json'
        }
    }
}
});

所以,我基本上是在尝试从另一家商店获取用户 ID,以便能够构建正确的 url。 这不起作用,我明白了:

Uncaught TypeError: Object #<Object> has no method 'getStore' 

这样做的正确方法是什么?

编辑:好的,我输入了一个虚拟 URL 并尝试使用侦听器更改它,现在这是我的商店:

Ext.define('MyApp.store.Post',{   extend:'Ext.data.Store', 
config: {
      fields: [
                        'title', 'link', 'author', 'contentSnippet', 'content'
                    ],
    proxy: {
        type: 'jsonp',
        url: 'https://ajax.googleapis.com/ajax/services/feed/load?v=1.0&q=http://feeds.feedburner.com/SenchaBlog',
        reader: {
            type: 'json',
            rootProperty: 'responseData.feed.entries'
        }
    },
    listeners: [
        {
            beforeload: function(){
               console.log("store loaded");   //I DON'T SEE THIS IN CONSOLE
               return true;
            }    
        }
    ]
},

});

【问题讨论】:

    标签: extjs model-view-controller sencha-touch-2


    【解决方案1】:

    基本上你没有做错任何事,但原因是 sencha touch 使用异步加载,并且似乎 Ext.getStore() 在定义你的商店时没有实例化。

    让我们试试这个方法:

    首先,在您的商店配置中为beforeload 事件添加一个监听器:

    Ext.define('MyApp.store.Post',{
    extend:'Ext.data.Store', 
    config: {
        model: 'MyApp.model.Post',
        proxy: {
            type: 'ajax',
            //url: you don't even need to set url config here, simply ignore it
            reader: {
                type: 'json'
            }
        }
    },
    listeners: [
        {
            fn: 'setUrl',
            event: 'beforeload'
        }
    ]
    });
    

    然后在同一个文件中声明这样的函数:

    setUrl: function(){
        this.getProxy().setUrl(Ext.getStore('UserData').getAt(0).data.userid);
        return true;
    }
    

    这样,可以确保在加载之前为您的商店代理设置 url。并且基本上在那个时候,所有的核心方法都被实例化了。

    更新:请在您的 Post 商店试试这个:

    Ext.define('MyApp.store.Post',{
       extend:'Ext.data.Store', 
       config: {
           //autoLoad: true,
              fields: ['title', 'link', 'author', 'contentSnippet', 'content'],
            proxy: {
                type: 'jsonp',
                url: 'dummy url',
                reader: {
                    type: 'json',
                    rootProperty: 'responseData.feed.entries'
                }
            },
       },
    
        initialize: function(){
            console.log("loaded!");
            this.getProxy().setUrl('https://ajax.googleapis.com/ajax/services/feed/load?v=1.0&q=http://feeds.feedburner.com/SenchaBlog');
            //return true;
        }    
    });
    

    在阅读了pull-to-refresh插件的源代码后,我看到Sencha Touch使用了Ext.data.Operation而不是Ext.data.Store.load()函数。因此,您必须将其放入 initialize 方法中。

    【讨论】:

    • 谢谢,但它仍然无法正常工作我现在收到 Uncaught Error: [ERROR][Ext.Base#callParent] You are using a ServerProxy but have not supplied it with a url. 并且商店无法加载..
    • 好吧,这是有道理的,我没有在我的视图中加载商店。我只有一个带有store: Post 的列表,我该怎么办?这是我的名单docs.sencha.com/touch/2.3.0/#!/api/Ext.plugin.PullRefresh
    • 让我们尝试将此配置添加到您的商店autoLoad: true。你现在得到了什么?
    • 如果将 autoLoad 设置为 false 并手动调用 Ext.getStore('Post').load() 会怎样?
    • @MinaHany:是的,它使用Ext.data.Operation 并将其作为参数应用到商店proxyread 操作。这就是为什么与loadbeforeload 无关的原因。有两种方法:覆盖getProxy(),或覆盖initialize。第二种解决方案显然更容易。
    【解决方案2】:

    使用Ext.data.StoreManager.lookup('UserData') 获取商店实例。

    但在你的情况下,我会在你使用用户 ID 的地方使用它:

    var postsStoreInstance = ...;
    postsStoreInstancegetProxy()._extraParams.userid = userid;
    

    它将查询参数添加到商店的代理 url

    【讨论】:

    • 这没什么区别,因为Ext.getStore()是简写方式
    【解决方案3】:

    你这样做的方式是正确的。您的商店定义的代码是什么?

    确保您的商店有storeId: 'UserData'

    查看这个工作示例:

    Ext.define('User', {
       extend: 'Ext.data.Model',
       fields: [
           {name: 'id'}
       ]
    });
    
    Ext.create( 'Ext.data.Store', {
       model: 'User',
       storeId: 'UserData'
    });
    
    Ext.define('MyApp.store.Post',{
       extend:'Ext.data.Store', 
       config: {
           model: 'MyApp.model.Post',
           proxy: {
               type: 'ajax',
               url: 'http://mywebsite.com/get?userid=' + Ext.getStore('UserData'),
               reader: {
                   type: 'json'
               }
           }
       }
    });
    

    【讨论】:

    • 请注意错误是Uncaught TypeError: Object #&lt;Object&gt; has no method 'getStore'
    • 您能否发布您对 store 'UserData' 的商店定义?