2

我有一个使用 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>…&lt;/tr>, <thead>…&lt;/thead>] [<tr>…&lt;/tr>, <thead>…&lt;/thead>, <table>…&lt;/table>, <div id="grid">…&lt;/div>, <body>…&lt;/body>, <html>…&lt;/html>]

console.log(target === targetb):
    false
4

1 回答 1

2

我没有看到任何僵尸观点的证据。

我创建了代码的一个分支并添加了一些额外的日志记录来检查视图实例,但我没有看到任何僵尸。每次都使用相同的 GridView 实例。每次排序时,子视图都会正确关闭。

http://jsfiddle.net/derickbailey/hadbf/4/

您看到的问题很可能是由使用target = $(e.target)和引起的targetb = this.$(...)。这是两个非常不同的语句,来自两个非常不同的 DOM 元素来源。

的第一个用途target = $(e.target)是直接从 DOM 运行。您正在单击的目标上运行一个选择器,它只是将该 DOM 元素包装在一个 jQuery 选择器对象中。

的第二个用途targetB = this.$(...)是使用 Backbone View's$el进行查找:this.$el.find("...")它将根据视图的 EL 返回结果。视图的 $eL 恰好包含属于 DOM 的元素。但是 $el 和事件不是同一个对象e,所以你永远不会target === targetb是真的。

...除非我完全误解了这个问题(在这一点上似乎很可能),我认为这里没有问题。

于 2012-05-30T17:44:48.260 回答