2

BackboneJSでルーティングをどのように処理する必要がありますか?ルーティングするとき、ビューを新しくアップした後、イベントをトリガーする必要がありますか、それともビューを直接レンダリングする必要がありますか?

2つのシナリオは次のとおりです。

トリガーイベント:

routes: {
    'orders/view/:orderId' : 'viewOrder'
},
viewOrder: function (orderId) {
    var viewOrderView = new ViewOrderView();
    vent.trigger('order:show', orderId);
}

私の見解では、私は持っています:

var ViewOrderView = Backbone.View.extend({
    el: "#page",
    initialize: function () {
        vent.on('order:show', this.show, this);
    },
    show: function (id) {
        this.id = id;
        this.render();
    },
    render: function () {
        var template = viewOrderTemplate({ id: this.id });
        this.$el.html(template);
        return this;
    }
});

または、このルートに行く必要があります:

routes: {
    'orders/view/:orderId' : 'viewOrder'
},
viewOrder: function (orderId) {
    var viewOrderView = new ViewOrderView({id : orderId });
    viewOrderView.render();
}

私の見解では、私は持っています:

var ViewOrderView = Backbone.View.extend({
    el: "#page",
    initialize: function () {
        //init code here
    },
    render: function () {
        var template = viewOrderTemplate({ id : this.id});
        this.$el.html(template);
        return this;
    }
});

バックボーンがイベント駆動型であることを考えると、これが最初のシナリオだと思いますが、2番目のシナリオは明らかにコードが少なくなっています。

また、3番目のシナリオは最初のシナリオでビューコードを保持することだと思いますが、2番目のルーターシナリオを取得します...ナビゲーションでビューをレンダリングしますが、他の場所でトリガーしたい場合に備えてイベントを公開します。

考え?

4

2 に答える 2

6

したがって、すべてのバックボーンの質問は、通常、多くのもっともらしい答えになります。この場合、2番目の例はより標準的/典型的なバックボーンパターンであると思います。ロードスピナーの処理とデータロード後の更新というトリッキーな問題は別として、ルーターの単純化された基本パターンは次のようになります。

routes: {
    'orders/view/:orderId' : 'viewOrder'
},

viewOrder: function (orderId) {
    //Use models to represent your data
    var orderModel = new Order({id: orderId});
    //models know how to fetch data for themselves given an ID
    orderModel.fetch();
    //Views should take model instances, not scalar model IDs
    var orderView = new OrderView({model: orderModel});
    orderView.render();
    //Exactly how you display the view in the DOM is up to you
    //document.body might be $('#main-container') or whatever
    $(document.body).html(orderView.el);
}

それが教科書のパターンだと思います。繰り返しになりますが、データのフェッチとデータの到着後に再レンダリングをトリガーするのは誰かという問題は注意が必要です。モデルがデータをフェッチするまでビューがそれ自体の「ロード」バージョンをレンダリングする方法を知っていて、フェッチが完了した後にモデルが変更イベントを発生させると、ビューはロードされたモデルデータで自分自身を再レンダリングするのが最善だと思います。ただし、そのロジックを別の場所に置く人もいます。次のsoundcloudの構築に関するこの記事は、フェッチされていないモデルの処理方法など、多くの非常に優れた「最先端の」バックボーンパターンを表していると思います。

一般に、必要に応じてコールバックまたはイベントを使用してコーディングできます。ただし、経験則として、いくつかの質問を自問することをお勧めします。

  1. このイベントに対応するのは、複数の独立した論理的な作業ですか?
  2. このイベントのソースを、それに応答して発生するものから切り離す必要がありますか?

それらの両方が「はい」である場合、イベントは適切であるはずです。両方が「いいえ」の場合は、単純な関数ロジックよりも適しています。「このURLに移動すると、このビューがトリガーされます」の場合、通常、両方の質問に対する答えは「いいえ」です。そのため、そのロジックをルーターのルートハンドラーメソッドにコーディングするだけで、それを実行できます。

于 2012-12-21T21:48:10.497 に答える
3

2番目のシナリオを使用します。最初のアプローチを使用するメリットはありません。それはこの方法でより多くの意味をなすでしょう(しかしそれでも議論の余地があります):

/* ... */
routes: {
    'orders/view/:orderId' : 'viewOrder'
},
viewOrder: function (orderId) {
    vent.trigger('order:show', orderId);
}
/* ... */
vent.on('order:show', function(orderId) {
    var viewOrderView = new ViewOrderView();
    viewOrderView.render();
});

var ViewOrderView = Backbone.View.extend({
    el: "#page",
    initialize: function (options) {
        this.orderId = options.orderId;
    },

    render: function () {
        var template = viewOrderTemplate({ 
            id: this.orderId 
        });
        this.$el.html(template);
        return this;
    }
});

このようにして、少なくともURLを更新せずにルートアクションをトリガーすることができます。しかし、おそらく同じ効果が得られるかもしれませんBackbone.router.viewOrder(1)。イベントはかなり強力ですが、本当に必要ない場合は使用しません。

于 2012-12-21T21:45:16.590 に答える