如何通过AJAX添加元素后更新缓存的jquery对象

时间:2014-01-13 17:47:00

标签: javascript jquery ajax

我正在尝试在jQuery中编写类似插件的函数,以便使用AJAX将元素添加到容器中。 它看起来像这样:

$.fn.cacheload = function(index) {
    var $this = $(this);
    $.get("cache.php", {{ id: index }).done(function(data) {
        // cache.php returns <div class='entry'>Content</div> ...
        $(data).insertAfter($this.last());
    });
}

我希望像这样使用它:

var entries = $("div.entry"),
    id = 28;

entries.cacheload(id);

认为这会加载另一个“条目”容器并将其添加到DOM中。

到目前为止这是有效的。但是当然保存缓存的jQuery对象(entries)的变量不会更新。因此,如果开头有两个div,你会添加另一个这个函数,它会在DOM中显示,但entries仍然只引用原来的两个div。

我知道你不能使用get的返回值,因为AJAX调用是异步的。但有没有办法更新缓存的对象,所以它包含通过AJAX加载的元素?

我知道我可以这样做并在插入后重新查询:

    $.get("cache.php", {{ id: num }).done(function(data) {
        $(data).insertAfter($this.last());
        entries = $("div.entry");
    });

但为此我必须直接引用保存缓存对象的变量。 有没有办法绕这个,所以功能是独立的? 我尝试重新分配$(this),但收到了错误。 .add()不更新缓存对象,它会创建一个新的(临时)对象。

非常感谢!

//更新:

约翰S在下面给出了一个非常好的答案。然而,我最终意识到对我来说其他东西实际上会更好。 现在,插件函数插入一个空白元素(同步),当AJAX调用完成时,该元素的属性会更新。这也确保了元素以正确的顺序加载。对于任何绊脚石的人来说,这是一个JSFiddle:http://jsfiddle.net/JZsLt/2/

1 个答案:

答案 0 :(得分:1)

正如你自己所说,ajax调用是异步的。因此,您的插件也是异步的。在ajax调用返回之前,您的插件无法将新元素添加到jQuery对象。另外,正如您所发现的,您无法真正添加到原始jQuery对象,您只能创建一个新的jQuery对象。

您可以做的是让插件将回调函数作为第二个参数。回调可以传递一个jQuery对象,该对象包含原始元素和新插入的元素。

$.fn.cacheload = function(index, callback) {
    var $this = this;
    $.get('cache.php', { id: index }).done(function(html) {
        var $elements = $(html);
        $this.last().after($elements);
        if (callback) {
            callback.call($this, $this.add($elements));
        }
    });
    return $this;
};

然后你可以打电话:

entries.cacheload(id, function($newEntries) { doSomething($newEntries); } );

当然,你可以这样做:

entries.cacheload(id, function($newEntries) { entries = $newEntries; } );

但是,在ajax调用返回之前,entries不会被更改,所以我看不到它有多大价值。

BTW:插件中的this是指jQuery对象,因此无需调用$(this)