2012-02-16 5 views
6

私はbackbone.jsのRailscastチュートリアルに従っており、キーボードコントロールを含むように機能を拡張したかったのです。私のショーのテンプレートにbackbone.jsでキーアップを文書にバインドするには

class Raffler.Views.EntryShow extends Backbone.View 
    template: JST['entries/show'] 

    events: 
    'click .back': 'showListing' 
    'keyup': 'goBack' 

    showListing: -> 
    Backbone.history.navigate("/", trigger: true) 

    goBack: (e) -> 
    console.log e.type, e.keyCode 

    render: -> 
    $(@el).html(@template(entry: @model)) 
    this 

私は、次のしている:私はタブ・キーを使用してバックリンクを選択した場合

<a href="#" class="back">Back</a> 
<%= @entry.get('name') %></td> 

が、その後、私が手にランダムキーを押す開始、私は私のショーのビューに以下を追加しました私のjavascriptコンソールに出力します。しかし、ページをロードしてリンクを選択せず​​にキーを押すだけで、私のコンソールには何も出力されません。

イベントをドキュメントにバインドすると、画面をロードするときに押されたキーを聞くことができます。

+1

[backbone.js - 入力からの値でコレクションをフィルタリングする]の複製が可能です。(http://stackoverflow.com/questions/9244773/backbone-js-filtering-a-collection-with-thevalue- from-a-input) –

+0

それは同じ機能ですが、重複して見えるのではないかと疑問に思うのですが、この人は、ビューの範囲を回避する方法、キーアップイベントをドキュメントにバインドする方法、単一入力。ビューのスコープの外側にある可能性が最も高いドキュメントです。彼の独自の例では、彼は彼が彼のビューのコンテナ要素にバインドしていることを意味する「キーアップ」にバインドします。これはページ全体ではない可能性が最も高いです。 – Sander

答えて

6

ビューのバックボーンの有効範囲を回避する必要があります。 ときあなたはこのような何かをやっている:

events: 
    'click .back': 'showListing' 
    'keyup': 'goBack' 

はあなたのビューのあなたのコンテナ要素で発生keyUpイベントにごgoBack機能を結合しています。代わりにそれを行うの

(ビューがレンダリングされるdivのデフォルト)、自分の視野の外に何かにバインドしたい場合(それは自身のビューの持っていない!(*)

Raffler.Views.EntryShow = Backbone.View.extend({ 
    template: JST['entries/show'], 

    events: { 
    'click .back': 'showListing' 
    }, 

    initialize: function() { 
    $('body').keyup(this.goBack); 
    }, 

    showListing: function() { 
    Backbone.history.navigate("/", trigger: true); 
    }, 

    goBack: function (e) { 
    console.log e.type, e.keyCode; 
    }, 

    render: function() { 
    $(this.el).html(this.template(entry: @model)); 
    return this; 
    } 

}); 

(*)備考に上記マークとして、あなたが最良のあなたの全ページ用のビュー(アプリビューまたはのようなものを持っている場合は、あなたがにバインドしたいアイテムが、それは自分のビューの持っていない場合にのみ、これを行いますあなたはそこでキーアップを縛ることができ、ちょうど例えばイベントApp.trigger('keypressed', e);を起こすことができます。

EntryShowビューで、そのアプリケーションのkeypressedイベントにバインドできます。

App.bind('keypressed', goBack); 

が遅延イベントまたはグループは、いくつかの状況に合わせてキー入力として、あなたが何かを行う必要があります覚えておいて、体内で起こるすべてのキー入力を発射として、大きなパフォーマンスヒットかもしれません。特に古いブラウザでは

+0

これは私のためにビューの初期ロード時に機能します。しかし、ユーザーがもう一度ビューにナビゲートすると、バインディングが再適用され、メソッドは各 'keyup'イベントで2回起動されます。 – wuliwong

+0

あなたは2つの方法でそれを解決することができます、バックボーンのようなビューマネージャーを使用することができます(または自分自身を書く)ビューを閉じたときにkeypressedイベントのバインドを解除します。または、バインドされたままにすることはできますが、処理された状態で処理します。 keypressedイベントにバインドするときは、一度だけ行います。keypressedprocessedクラスがコンテナにあるかどうかを確認してください。もしそうでなければ、バインドしてください。 (バインド後、2回目の訪問時に再度バインドしないようにクラスを設定する必要があります) – Sander

4

イベントは、表示要素@elにスコープされます。 document上のイベントをキャプチャするには、その自分自身をロールバックする必要があります:

initialize: -> 
    $(document).on "keyup", @goBack 

remove: -> 
    $(document).off "keyup", @goBack 

は、トリックを行う必要があります。

+1

この回答はバインディングの削除に対処しますが、 'remove()'は自動的に呼び出されません。ユーザーがビューから移動するたびに呼び出されるものが必要です。代わりに、私は現在のビューでそれらを適用する前に、以前のバインディングが削除されていることを確認します。ちょっとハッキリですが、うまくいきます。 – wuliwong

+0

@wuliwongうん、 'remove()'が自動的に呼び出されるとは思わない。ユーザーがビューから移動したときに自動的に呼び出される 'initialize'の反対は何ですか?ドキュメントの1つを見つけることができませんでした。どんな解決策ですか? –

関連する問題