我正在尝试在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/答案 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)
。