1

初めてjsrender/jsviewsを使用してみました。素晴らしいように見えますが、生成されたコンテンツのイベント ハンドラーを動的にバインドする方法の明確なドキュメントや例が見つかりません。

たとえば、純粋な jQuery の古いアプローチは次のとおりです。

オブジェクトのコレクションをレンダリングする Bean クラスからのコード:

container = $('#tabs-my');
this.load( // Obtain array of objects
    $.proxy(function(list){
        container.html('');
        list.forEach(
            $.proxy(function(it, i){
                container.append(this.renderItem(it));
            }
            ,this)
        );
    }
    ,this)
);

そして、オブジェクト自体の render メソッドで:

,renderItem: function(/*Specialist*/ it){
    var container = $('<div class="specialist-item" />')
    container.append(
        $('<span class="x">Remove</span>').click($.proxy(function(){
            this.removeSpecialistFromList(it.id)
        }
        ,this))
    );
    container.append(
        $('<span class="x">Edit</span>').click($.proxy(function(){
            this.renderSaveForm(container)
        }
        ,this))
    );
    container.append('<p><b>' + it.name + '</b> &nbsp; <i>' + it.phone + '</i></p>' +
    '<p>' + it.skill + '</p>' +
    ( it.city ? '<p>' + it.city.name + '</p>' : ''));
    return container;
}

タグ自体に外部識別子を使用せずに、現在のオブジェクトのクロージャー コンテンツを介してハンドラーをバインドすることに注意してください。次に、テンプレートを使用して、コンテンツを視覚化から分離してみます。

私のテンプレート:

<div class="specialists-list">
    Items in list: {{:specialists.length}}
    {^{for specialists}}
        <div class="specialist-item">
            <span class="x">Remove</span><span class="x">Edit</span>

            <p><b class="name">{{:name}}</b> &nbsp; <i class="phone">{{:phone}}</i></p>
            <p class="skill">{{:skill}}</p>
            <p class="city">{{:city.name}}</p>
        </div>
    {{/for}}
</div>

そして次のようにレンダリングされます:

var template = $.templates({
    specialistsTmpl: tmpl
});
$.templates.specialistsTmpl.link(container, {
    specialists: list
});

次のような属性で一般的なハンドラーを使用して実行できることを認識しています。

<span class="x" data-id="{{:id}}">Edit</span>

そして、そのオブジェクトを外部から再度取得してみてください。しかし、これは回避策であり、望ましくありません。テンプレートまたはヘルパー、カスタム タグを介してハンドラーをバインドする方法はありますか?

4

2 に答える 2

2

http://www.jsviews.comには、イベント バインディングや、データ項目の削除や挿入などのハンドラーを含むサンプルが多数あります。ここの例を見ましたか: http://www.jsviews.com/#samples/editable - 同じシナリオに対する 4 つの異なるアプローチを見つけることができます。

例えば:

テンプレート

{^{for languages}}
  <input data-link="name" />
  <img class="removeLanguage" .../>
{{/for}}

コード:

$.link.movieTmpl("#movieList", app)
  .on("click", ".removeLanguage", function() {
    var view = $.view(this);
    $.observable(view.parent.data).remove(view.index);
    return false;
  });

-の使用に注意してください-クリックされvar view $.view(this);た要素 ( ) を渡し、そこから取得できる(アイテム インデックス - 配列の反復の場合)、(現在のデータ アイテム - あなたの)、(あなたの場合は配列)などになります。this$.view(clickedElement)viewview.indexview.dataspecialist itemview.parent.dataspecialists

もちろん、view.dataは現在のデータ項目であるため、データ項目が実際にビュー モデルである場合は、メソッドを使用してメソッドを呼び出すことができます: view.data.someMethod(...).

ただし、バインディング ハンドラーに jQuery を使用する代わりにon()、次のように宣言型バインディングをテンプレートで直接使用できます。

{^{for specialists}}
    <div class="specialist-item">
        <span class="x" data-link="{on removeMe}">Remove</span> ...
        ...
    </div>
{{/for}}

あなたの専門家がremoveMe()方法を持っていると思います。バインディングは"{on ...}"デフォルトでクリック イベントにバインドされ、データのメソッドやヘルパーなどにバインドできます。

この例を見てみましょう: http://jsfiddle.net/BorisMoore/cGZZP/ - {on ...}2 次元配列を変更するためのヘルパーへのバインドに使用します。

{on ...}近いうちに、バインディングを使用していくつかの新しいサンプルを作成したいと考えています。

ところで、イベント バインディングを行うために onAfterCreate を使用することはお勧めしません。上記のアプローチのいずれかが優れており、イベント バインディングを正しく破棄することが保証されます。

于 2014-07-09T04:52:55.993 に答える
0

100% 完全に理解しているとは言えませんが、理解していると信じています。別のアプローチを使用したい。jQueryの.onを見てください。私はほとんど常にそれを使用するように切り替えました。コールバック関数を変更する必要はありません。それは本当にかなりいいです。

私の場合、何千ものイベント ハンドラーを作成していたため、パフォーマンスが低下していました。そこで、.on の使用に切り替えて、問題を解決しました。

これはあなたの質問に正確に答えるものではありません...しかし、より良い解決策だと思います。

于 2014-07-07T19:56:51.507 に答える