2

BackboneMarionetteCompositeViewを使用して作成された非常に単純なテーブルがあります。このテーブルの唯一の要件は、データを表示し、ユーザーがヘッダー行をクリックしてデータを並べ替えることができることです。テーブルが並べ替えられると、ヘッダー列の並べ替えに使用される列にクラスのタグが付けられ、CSSを使用して矢印を表示できるようになります(例:'class = "sort asc"')。

問題は次のとおりです。ヘッダー行がクリックされると、(event.targetを介して)コールバックに渡される要素は、DOM上にあるテーブルの一部ではありません。代わりに、Chromeのデバッグツールを使用すると、ターゲット要素は実際にはテンプレートスクリプトブロックの一部であり、ユーザーが実際に表示する要素ではないように見えます。

私が今持っている最善の回避策は、テンプレート内のクローンから一意の情報を取得することによって、実際にDOMにアタッチされている要素を検索することです。

複合ビューコード(Derick BaileyのサンプルFiddleの1つから借用)は次のとおりです。

// 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のバグですか、それとも単にこれをすべて間違っているのでしょうか?

**編集**これは、2つの要素の異なる親階層を示すコンソール出力です。

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.$(...)ます。これらは2つの非常に異なるステートメントであり、DOM要素の2つの非常に異なるソースから機能します。

の最初の使用はtarget = $(e.target)、DOMから直接実行することです。クリックされたターゲットでセレクターを実行しています。これは、そのDOM要素をjQueryセレクターオブジェクトでラップしているだけです。

の2番目の使用法はtargetB = this.$(...)、バックボーンビューを使用$elして検索を実行することです。this.$el.find("...")これにより、ビューのELに基づいて結果が返されます。ビューの$eLには、DOMの一部である要素が含まれています。eただし、$ elはイベントと同じオブジェクトではないため、 target === targetbtrueになることはありません。

...問題を完全に誤解していない限り(現時点では非常に可能性が高いと思われます)、ここに問題はないと思います。

于 2012-05-30T17:44:48.260 に答える