我有一个使用 Backbone Marionette CompositeView 创建的相当简单的表。此表的唯一要求是它显示数据并允许用户通过单击标题行对其进行排序。对表格进行排序时,用于对标题列进行排序的列用类标记,以允许使用 CSS 显示箭头(例如,'class="sort asc"')。
这就是问题所在:单击标题行时,传递给回调(通过 event.target)的元素不是 DOM 上的表的一部分。相反,使用 Chrome 的调试工具,似乎目标元素实际上是模板脚本块的一部分,而不是用户实际看到的元素。
我现在最好的解决方法是通过从模板中的克隆检索唯一信息来查找实际附加到 DOM 的元素。
这是复合视图代码(借自 Derick Bailey 的示例 Fiddle 之一):
// The grid view
var GridView = Backbone.Marionette.CompositeView.extend({
tagName: "table",
template: "#grid-template",
itemView: GridRow,
events: {
'click th': 'doSort'
},
doSort: function(event) {
var target = $(event.target);
this.collection.sortByField(target.data('sortby'));
target.parent('tr').find('.sort').removeAttr('class');
target.addClass('sort ' + this.collection.sortdir);
debugger; // NOTE: no change to elements in the DOM. WTH?
target = this.$('[data-sortby=' + target.data('sortby') + ']');
target.parent('tr').find('.sort').removeAttr('class');
target.addClass('sort ' + this.collection.sortdir);
debugger; // NOTE: DOM updated.
},
appendHtml: function(collectionView, itemView) {
collectionView.$("tbody").append(itemView.el);
}
});
模板也很简单:
<script id="grid-template" type="text/template">
<thead>
<tr>
<th data-sortby="username">Username</th>
<th data-sortby="fullname">Full Name</th>
</tr>
</thead>
<tbody></tbody>
</script>
可以在这里找到 Derek 的原始演示 Fiddle 的一个分支,用于演示问题:http: //jsfiddle.net/ccamarat/9stvM/14/
我有点绕道。我的问题是,我似乎产生了某种僵尸视图;这是一个 jQuery/Backbone/Underscore 错误,还是我只是把这一切都搞错了?
** 编辑 ** 这是显示两个元素的不同父层次结构的控制台输出:
console.log(target, targetb):
[<th data-sortby="username" class="sort asc">Username</th>] [<th data-sortby="username">Username</th>]
console.log(target.parents(), targetb.parents()):
[<tr>…</tr>, <thead>…</thead>] [<tr>…</tr>, <thead>…</thead>, <table>…</table>, <div id="grid">…</div>, <body>…</body>, <html>…</html>]
console.log(target === targetb):
false