4

ユーザーがログインする必要があるアプリケーションを開発しています。この意味では、ユーザーが登録されていないため、ログインはわずかに異なります。名前と部屋の名前を入力して接続します。ルーム自体には、次のようなユーザーに必要なすべての設定が含まれています。

  • 部屋の名前
  • 設定の表示 - オプションをオンまたはオフにできます
  • 等...

だから私が探しているのは、ルートイベントにフックすることです。これにより、ユーザーが/loginログインしていない場合にルートに移動するように強制できます.

確かに、各ルートに条件を追加せずにこれを行う DRY 方法が必要ですか?

4

4 に答える 4

4

Backbone の Routerには、executeオーバーライドできるメソッドがあります。コールバックが呼び出される前に、ルートが一致するたびに呼び出されます。

var Router = Backbone.Router.extend({
  execute: function(callback, args) {
    // Do what you want here! 
    if (callback) callback.apply(this, args);
  }
});

このメソッドは、2014 年 2 月 13 日の 1.1.1 リリースで追加されました。

于 2014-12-30T20:18:46.903 に答える
3

私の頭に浮かぶ唯一のオプションは、現在の関数を上書きすることですRouter.route。現在、次のようになっています

route: function(route, name, callback) {
  if (!_.isRegExp(route)) route = this._routeToRegExp(route);
  if (!callback) callback = this[name]; // this is of interest
  Backbone.history.route(route, _.bind(function(fragment) {
    var args = this._extractParameters(route, fragment);
    callback && callback.apply(this, args);
    this.trigger.apply(this, ['route:' + name].concat(args));
    Backbone.history.trigger('route', this, name, args);
  }, this));
  return this;
},

やりたいことは、必要な条件が満たされているかどうかをチェックする関数ですべてのコールバックをラップし、ラップピーを呼び出すか、ログインに再ルーティングすることです。ここではアンダースコアのwrap- 関数が役立ちます。

route: function(route, name, callback) {
  ... // same as above
  if (!callback) callback = this[name];
  _.wrap(callback, function(cb) {
    if (userIsLoggedIn()) {
      cb();
    } else {
      this.navigate("url/to/login");
    }
  });
  ... // same as above
},

もちろん、無限ループを作成しないように、実際のログイン ルートのチェックを追加する必要があります。

編集:

ソースを変更する必要はありません。これを行う最も簡単な方法は次のとおりです。

var CustomRouter = Router.extend({
  route: function() {
    // your overwrite here
  }
});

これは Backbone にネイティブであるため、コメントにあるものよりもこれを使用してください!

お役に立てれば

于 2012-12-20T11:59:42.957 に答える
2

@jakeeの回答と@Joel Nationのコメントを拡張したいと思います。this予想通り、影響を受けたルートで作業を行うのに苦労しました。「これは未定義です」というメッセージが表示されました。それを機能させた最終的なコードの下:

  Backbone.Router.prototype.route = function(route, name, callback) {
    if (!_.isRegExp(route)) route = this._routeToRegExp(route);
    if (_.isFunction(name)) {
      callback = name;
      name = '';
    }
    if (!callback) callback = this[name];
    // here my custom code
    callback = _.wrap(callback, _.bind(function(cb) {
      if (name == 'login' || sessionModel.authenticated()) {
        _.bind(cb, this)();
      } else {
        this.navigate('login', {trigger: true});
      }
    }, this));
    // finish my custom code
    var router = this;
    Backbone.history.route(route, function(fragment) {
      var args = router._extractParameters(route, fragment);
      callback && callback.apply(router, args);
      router.trigger.apply(router, ['route:' + name].concat(args));
      router.trigger('route', name, args);
      Backbone.history.trigger('route', router, name, args);
    });
    return this;
  };

注意_.wrap_.bindthisください。あなたが期待するものです。

于 2013-04-30T14:51:34.867 に答える
1

アプリケーションを初期化するコードで:

// Initialize router(s)
Backbone.history.on("route", function() {
    if (!authenticated) Backbone.history.navigate("/login", true);
});
Backbone.history.start();
于 2012-12-20T14:40:05.570 に答える