我使用以下代码加载两个underscore.js模板。单击第一个链接后,将加载骨架模板。第一个触发器执行find bind,它正确执行loadBookmarks函数,但'loaded'触发器永远不会触发,loadFriendBookmarks永远不会执行。为什么是这样?还有另一种方法可以实现这一目标吗?
$('#bookmarks-link').click(function() {
$('#bookmarks-count').text("0");
var skeleton = modalTemplate();
$('#bookmarks').append(skeleton);
$('#bookmarks').trigger('skeleton');
});
$('#bookmarks').bind('skeleton', function() {
$('#bookmarks .thumbnails').loadBookmarks( getBookmarksUrl(1) );
// If I add an alert('hi') here, it works perfectly.
$('#bookmarks').trigger('loaded');
});
$('#bookmarks').bind('loaded', function() {
$('#bookmarks .thumbnails a').each(function() {
$(this).bind('click', function() {
$('#bookmarks .bookmarks-table tbody').empty();
$('#bookmarks .bookmarks-table tbody').loadFriendBookmarks(
getFriendBookmarksUrl($(this).attr('data-item'))
);
});
});
});
如此有趣,触发器可以正常工作:如果我在loadBookmarks和触发器之间粘贴警报,一切正常。如果我拿出来,那就没有。知道为什么吗?
答案 0 :(得分:2)
根据您的描述和常识,听起来loadBookmarks()
加载来自远程源的数据,例如ajax调用。这意味着trigger('loaded')
可以在 loadBookmarks()
收到数据之前触发。您可以向loadBookmarks()
添加回调参数并在那里触发事件:
$('#bookmarks .thumbnails').loadBookmarks( getBookmarksUrl(1) , function() {
$('#bookmarks').trigger('loaded');
});
但这需要您的loadBookmarks
知道在收到数据并创建所需的HTML后调用此函数 - 如果没有看到loadBookmarks
中的实际代码,我无法证明这一点。< / p>
其他建议:不要以这种方式绑定处理程序,而是使用event delegation:
$('#bookmarks').on('click', '.thumbnails a', function(e) {
e.preventDefault(); // don't want the link to actually be followed, do we
var url = getFriendBookmarksUrl($(this).attr('data-item'));
if(url) { // in case it's clicked before the data attribute is set
var $tbody = $('#bookmarks .bookmarks-table tbody');
$tbody.empty();
$tbody.loadFriendBookmarks(url);
}
});
这意味着匹配选择器'#bookmarks .thumbnails a'的所有元素将调用此单击处理程序,即使它们已在调用后添加到文档中{ {1}}。这意味着您甚至可以在调用on
之前委派这些事件,完全不需要loadBookmarks
事件。另外,这样您在内存中只有一个处理函数副本,而不是loaded
为每个bind
节点创建了函数的单独副本。
答案 1 :(得分:0)