45

私の単純なプロジェクトには、2 つのビューがあります - 広告申込情報ビュー (ブランド) とアプリです。複数のアイテムを選択できる機能を追加しました:

var BrandView = Backbone.View.extend({
...いくつかのコード...
    toggle_select: 関数() {
        this.model.selected = !this.model.selected;
        if(this.model.selected) $(this.el).addClass('selected');
        そうでなければ $(this.el).removeClass('selected');
        これを返します。
    }
});

var AppView = Backbone.View.extend({
...いくつかのコード...
    delete_selected: 関数() {
        _.each(Brands.selected(), 関数(モデル){
            model.delete_selected();
        });
        false を返します。
    }、
});

つまり、いくつのアイテムが選択されているか知りたいのです。このセットアップでは、選択はモデルに影響を与えないため、イベントは発生しません。そして、MVC の概念から、ビューは他のビューと直接やり取りしてはならないことを理解しています。では、BrandViews で何かが選択されていることを AppView はどのようにして知るのでしょうか?

より具体的には、AppView を使用して項目がいくつ選択されたかを把握するので、複数選択されている場合は、複数選択用のメニューを表示します。

4

7 に答える 7

74

Backbone pub/subイベントに関するこのディスカッションを読んでおくとよいでしょう。

http://lostechies.com/derickbailey/2011/07/19/references-routing-and-the-event-aggregator-coordinating-views-in-backbone-js/

グローバルイベントメカニズムとして追加したいと思います。

Backbone.pubSub = _.extend({}, Backbone.Events);

次に、1つのビューで、イベントをトリガーできます。

Backbone.pubSub.trigger('my-event', payload);

そして別の方法であなたは聞くことができます:

Backbone.pubSub.on('my-event', this.onMyEvent, this);
于 2012-04-03T09:59:00.907 に答える
7

Addy Osmani がメディエーター パターンhttp://addyosmani.com/largescalejavascript/#mediatorpatternと呼んでいるものを使用します。記事全体は一読の価値があります。

基本的には、イベントをサブスクライブして公開できるイベント マネージャーです。したがって、AppView はイベント、つまり「選択済み」に添え字を付けます。次に、BrandView は「選択された」イベントを公開します。

私がこれを気に入っている理由は、ビューを直接バインドしなくても、ビュー間でイベントを送信できるからです。

例えば

var mediator = new Mediator(); //LOOK AT THE LINK FOR IMPLEMENTATION

var BrandView = Backbone.View.extend({
    toggle_select: function() {
        ...
        mediator.publish('selected', any, data, you, want);
        return this;
    }
});

var AppView = Backbone.View.extend({
    initialize: function() {
        mediator.subscribe('selected', this.delete_selected)
    },

    delete_selected: function(any, data, you, want) {
        ... do something ...
    },
});

このように、アプリ ビューは、「選択された」イベントを発行するのが BrandView であるか FooView であるかを気にせず、イベントが発生したことだけを気にしません。その結果、ビューだけでなく、アプリケーションのパーツ間のイベントを管理するための保守可能な方法であることがわかりました。

「ファサード」についてさらに読むと、優れた権限構造を作成できます。これにより、「AppView」のみが「選択した」イベントをサブスクライブできると言えます。イベントがどこで使用されているかが非常に明確になるので、これは役に立ちます。

于 2012-04-02T23:02:23.053 に答える
1

同様のニーズがある私の場合は次のとおりです。バックボーンの listenTo は、タイムアウトまたは認証されていない要求のためにログイン ページにリダイレクトするソリューションのように見えました。

ルーターにイベント ハンドラーを追加し、次のようなグローバル イベントをリッスンするようにしました。

Backbone.Router.extend({
    onNotAuthenticated:function(errMsg){
        var redirectView = new LoginView();
        redirectView.displayMessage(errMsg);
        this.loadView(redirectView);
    },
    initialize:function(){
        this.listenTo(Backbone,'auth:not-authenticated',this.onNotAuthenticated);  
    },
    .....
});

そして私のjquery ajaxエラーハンドラーで:

$(document).ajaxError(
    function(event, jqxhr, settings, thrownError){
        .......
        if(httpErrorHeaderValue==="some-value"){
             Backbone.trigger("auth:not-authenticated",errMsg);
        }
    });     
于 2014-08-28T05:58:10.443 に答える
1

投稿で既に言及しているこの問題を無視して、グローバルな Backbone.Event オブジェクトとの間でイベントをバインドしてトリガーすることができます。これにより、あらゆるものが他のあらゆるものと通信できるようになります。間違いなく最善の解決策ではありません。互いにチャットしているビューがある場合は、それをリファクタリングすることを検討する必要があります。しかし、そこに行きます!お役に立てれば。

于 2012-04-02T22:59:18.917 に答える
0

ジョンが上で提案したのと同じように、このシナリオでは Mediator パターンが非常にうまく機能します

シンプルで優れたBackbone.Mediatorプラグインを使用して巻き上げ、AMD Viewモジュールをシームレスに連携させます=)

于 2012-09-05T04:04:45.780 に答える
0

同じモデル オブジェクトを使用します。AppView はコレクションで初期化でき、BrandView はそのコレクションの 1 つのモデルで初期化できます。分岐オブジェクトの属性が変更されると、そのモデルへの参照を持つ他のコードはそれを読み取ることができます。

コレクションを介して取得するいくつかのブランドがあるようにしましょう。

var brands = new Brands([]);
brands.fetch();

次に、AppView と各モデルの BrandView の配列を作成します。

var appView = new AppView({brands: brands});
var brandViews = brands.map(function(brand) {
  return new BrandView({brand: brand});
});

appView と brandViews の両方が同じモデル オブジェクトにアクセスできるようになったため、いずれかを変更すると、次のようになります。

brands.get(0).selected = true;

次に、それを参照するビューからもアクセスされると変更されます。

console.log(appView.brands.get(0).selected); // true
console.log(brandViews[0].brand.selected)    // true
于 2012-04-02T23:02:47.860 に答える