我有一个相当简单的表,它是使用主干木偶CompositeView创建的。此表的唯一要求是显示数据并允许用户通过单击标题行对其进行排序。对表进行排序时,用于对标题列进行排序的列将使用类进行标记,以允许使用CSS显示箭头(例如“class=”sort asc“)。
问题是:当单击标题行时,传递给回调(通过event.target)的元素不是DOM上的表的一部分。相反,使用Chrome的调试工具,目标元素实际上是模板脚本块的一部分,而不是用户实际看到的元素。
我现在所做的最好的解决方法是通过从模板中的克隆中检索唯一信息来查找实际附加到DOM的元素。
以下是复合视图代码(借用自德里克·贝利的一个小提琴样本):
// 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最初的演示小提琴的叉子经过修改以演示问题,可以在这里找到:http://jsfiddle.net/ccamarat/9stvM/14/
我有点曲折。我的问题是,我似乎有一个催生的僵尸视图;这是一个jQuery/骨干/下划线错误,还是我只是把这一切都搞错了?
**编辑**这是控制台输出,显示两个元素的不同父层次结构:
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
我看不到任何僵尸观点的证据。
我创建了一个代码分支,并加入了一些额外的日志来检查视图实例,但我并没有看到任何僵尸。每次都使用相同的GridView实例。每次排序时,子视图都被正确关闭。
http://jsfiddle.net/derickbailey/hadbf/4/
您看到的问题可能是由使用target=$(e.target)
和targetb=this引起的$(...)代码>。这是两个非常不同的语句,它们来自两个非常不同的DOM元素源。
target=$(e.target)
的第一次使用直接从DOM运行。您正在单击的目标上运行选择器,它只是将DOM元素包装到jQuery选择器对象中。
第二次使用targetB=this$(...)
正在使用主干视图的$el
执行查找:此操作$埃尔。查找(“…”)代码>将根据视图的EL返回结果。视图的$eL恰好包含DOM的一部分元素。但是$el与
e
事件不是同一个对象,因此您永远不会得到target===targetb
为真的结果。
... 除非我完全误解了这个问题(在这一点上似乎很有可能),否则我认为这里没有问题。