【问题标题】:ExtJS 4 - Update/Refresh single recordExtJS 4 - 更新/刷新单条记录
【发布时间】:2011-09-07 12:13:07
【问题描述】:

我有一个问题困扰着我。

我有一个网格,当我 dblclick 一个项目时,我想打开一个窗口来编辑该项目。很标准的东西。问题是,我想确保记录是最新的,因为使用该程序的其他人可能已经更改甚至删除了它。

我可以重新加载商店,但我只想检查一个特定的记录...所以我想我会去获取数据,建立另一条记录并替换商店中的现有记录,但我真的很想知道最好的方法做到这一点

请记住 RESTful 代理对我来说不是一个选项,即使我不知道更新操作在这种情况下是否有效(服务器 -> 客户端)。

编辑: 这可能会帮助某人: 我所做的只是将数据和原始对象从新记录复制到旧记录,然后“提交”更改。为我工作。

谢谢。

【问题讨论】:

    标签: javascript extjs extjs4 extjs-mvc


    【解决方案1】:

    ExtJS 4.1

    我遇到了类似的问题,并尝试过实验

    sStore.load({ id: mskey, addRecords: true });

    其中 mskey 是当前加载记录的 uuid。

    没有首先删除现有记录(作为实验),它更新与来自服务器的新数据具有相同 ID 的现有记录(通过模型 --> REST 代理)。完美的!

    我知道您说您没有使用 REST 代理,但这可能有助于其他发现此帖子的人搜索您的主题名称等搜索词(这就是我来到这里的方式!)

    所以,'addRecords' 似乎意味着添加更新。

    仅供参考, 穆雷

    【讨论】:

    • 不幸的是,这会重置滚动位置并始终在我的网格末尾添加更新的记录。我使用了此处找到的脚本的修改版本:vadimpopa.com/…
    【解决方案2】:

    执行此类操作的最佳方法是在打开窗口的事件中重新加载记录。因此,例如,您要将网格存储中的记录加载到窗口内的表单中,您可以使用您的模型从 id 加载。

    Item.load(id, { success: function(r) { form.loadRecord(r); } });
    

    保存后,您可能还应该在网格视图上调用刷新,这将重绘来自保存事件的更改。如果您担心性能,也可以在商店中的确切记录上使用 refreshNode (see grid view documentation)。

    当然你不必使用restful代理,你可以使用任何代理,只要它会加载单个记录。

    【讨论】:

    • 加载功能(在模型上)建立另一条记录(这就是为什么发布这个问题:D)当我 dblclick 项目时我已经获得了记录,我只想重新加载它,而不是建造另一个,或者如果是这样,如何干净地替换旧的。谢谢西蒙。
    • 如果你想检查服务器的新鲜度,那么你将不得不加载一个新版本。如果您只想坚持使用网格的后备存储,而不是使用独立模型,则必须从存储中删除记录,然后使用刚刚抓取的 url 在网格存储上加载({add: true})相关记录。
    • 所以,没有办法重新加载它......好的,谢谢,我会接受你的回答,因为它实际上帮助我解决了“刷新网格”问题。我担心当我删除然后添加(或反之亦然)有问题的记录时它会闪烁或其他东西。谢谢。
    • 这个解决方案很糟糕,因为您正在内存中创建另一个对象 - 如果您更新新加载的项目,商店中的项目将不同步。
    • 嗨西蒙,事实上我很想看到你在上面提供的链接,但它不起作用。请问可以发新链接吗?
    【解决方案3】:

    对于 ExtJS 4.1,这里有一个覆盖:

    在 CoffeeScript 中:

    # Adds "reload" to models
    Ext.define "Ext.ux.data.Model",
    
        override: "Ext.data.Model",
    
        # callBack is called with success:boolean
        reload: (callBack) ->
            Ext.getClass(@).load @getId(),
                success : (r, o) =>
                    for k, v of r.data
                        @data[k] = v
                    @commit()
                    callBack(true) if Ext.isFunction(callBack)
    
                failure: =>
                    callBack(false) if Ext.isFunction(callBack)
    

    在 JS 中(未测试):

    Ext.define("Ext.ux.data.Model", {
    
        override: "Ext.data.Model",
    
        reload: function(callBack) {
    
            var me = this;
            return Ext.getClass(this).load(this.getId(), {
                success: function(r, o) {
                    var k;
                    for (k in r.data) {
                        me.data[k] = r.data[k];
                    }
                    me.commit();
                    if (Ext.isFunction(callBack)) {
                        callBack(true);
                    }
                },
                failure: function() {
                    if (Ext.isFunction(callBack)) {
                        callBack(false);
                    }
                }
            });
        }
    });
    

    【讨论】:

    • 这不是修改私有data 属性的好主意。最好改用set 方法。
    • @AlexeySolonets set 会将记录标记为“脏”,此处并非如此。
    • 当然我们应该使用suspendEventscommitresumeEvents
    【解决方案4】:

    我在 Ext.data.Model 上创建了一个覆盖,以添加可用于更新现有记录(模型实例)的数据的附加方法。

    Ext.define('Ext.overrides.data.Model', {
        override: 'Ext.data.Model',
    
        /**
         * Refresh the data of a record from the server
         */
        reloadData: function(cb) {
             var me = this;
    
             var id = me.getId();
    
             Ext.ModelManager.getModel(me.modelName).load(id, {
                callback: function(record, operation, success) {
                    if (!success) {
                        Ext.Error.raise('Problem reloading data from server in record');
                    }
                    if (!record) {
                        Ext.Error.raise('No record from server to reload data from');
                    }
                    //change the data of the record without triggering anything
                    Ext.apply(me.data, record.getData());
    
                    //call a final callback if it was supplied
                    if (cb) {
                        cb.apply(me, arguments);
                    }
                }
            });
    
            return me;
         }
    });
    

    这就是你可以使用它的方式。其实很简单:

    myRecord.reloadData(function(record, operation, success) {
        //Done updating the data in myRecord
    });
    

    在内部,它使用关联模型上的加载方法来创建新记录。该新记录基于与调用 reloadData 方法的原始记录相同的 id。在回调中,新记录的数据应用于原始记录的数据。没有触发任何事件,这可能是您想要的。

    这是分机 4.2.1。这个解决方案可能有几十个场景被破坏,但我们总是可以改进,不是吗。

    更新:这个解决方案基本上实现了与@Drasill 相同的解决方案。哦,好吧……不过这个已经过测试了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-30
      • 2014-10-17
      • 2021-10-16
      • 2015-07-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多