Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/371.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript backbone.js块路由执行_Javascript_Model View Controller - Fatal编程技术网

Javascript backbone.js块路由执行

Javascript backbone.js块路由执行,javascript,model-view-controller,Javascript,Model View Controller,是否可以仅使用路由器在backbone.js中阻止路由执行 我知道每个路由都有一个回调方法,我可以在其中检查路由是否被允许,我只是不知道如何基于viewmodel上的属性(canNavigate)阻止执行 我还想让它在未指定为路由的url上工作(sammy.js不能这样做,主干网可以这样做吗?)。例如: 当route#/contact打开时,调用viewmodel上的活动方法“contact”。 当从#/contact导航到任何其他url时,如#/page1、/page2或google.com

是否可以仅使用路由器在
backbone.js
中阻止路由执行

我知道每个路由都有一个回调方法,我可以在其中检查路由是否被允许,我只是不知道如何基于viewmodel上的属性(canNavigate)阻止执行

我还想让它在未指定为路由的url上工作(
sammy.js
不能这样做,主干网可以这样做吗?)。例如:

当route
#/contact
打开时,调用viewmodel上的活动方法“
contact
”。 当从
#/contact
导航到任何其他url时,如
#/page1
/page2
google.com
我希望调用contact viewmodel上的canNavigate方法。 如果返回false,则应该阻止URL的路由,并显示一条消息(我不需要代码来显示消息等,如果可能的话,只需要backbone.js代码)

使用
backbone.js
,这可能吗?
如果不是,那么还有哪个框架(除了
sammy.js
,因为我们已经尝试过了)可以做到这一点呢?

如果编写路由器扩展,每个框架都是可能的。这可能比问这个问题花费更少的时间。我不知道主干网是否支持它,我会检查代码

这是您正在寻找的方法:

route: function(route, name, callback) {
  if (!_.isRegExp(route)) route = this._routeToRegExp(route);
  if (!callback) callback = this[name];
  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;
},
正如您所看到的,它只是运行回调,并不阻止任何操作

例如,您可以通过以下方式对其进行扩展:

var RouteError(message) {
    this.name = "RouteError";
    this.message = (message || "");
}
RouteError.prototype = Error.prototype;


var MyRouter = function (){
    Backbone.Router.apply(this, arguments);
};
MyRouter.prototype = Object.create(Backbone.Router.prototype);
MyRouter.prototype.constructor = MyRouter;
_.extend(MyRouter.prototype, {
    route: function(route, name, callback) {
      if (!_.isRegExp(route)) route = this._routeToRegExp(route);
      if (!callback) callback = this[name];
      Backbone.history.route(route, _.bind(function(fragment) {
        var args = this._extractParameters(route, fragment);
        try {
            callback && callback.apply(this, args);
        }
        catch(e)
        {
            if (e instanceof RouteError)
                return this;
            else
                throw e;
        }
        this.trigger.apply(this, ['route:' + name].concat(args));
        Backbone.history.trigger('route', this, name, args);
      }, this));
      return this;
    },
});
var loadUrl = Backbone.History.prototype.loadUrl;
Backbone.History.prototype.loadUrl = function (fragmentOverride){
    try {
        loadUrl.apply(this, arguments);
    }
    catch (e){
        if (e instanceof RouteError)
            return ;
        else
            throw e;
    }

};
或者这样:

var RouteError(message) {
    this.name = "RouteError";
    this.message = (message || "");
}
RouteError.prototype = Error.prototype;


var MyRouter = function (){
    Backbone.Router.apply(this, arguments);
};
MyRouter.prototype = Object.create(Backbone.Router.prototype);
MyRouter.prototype.constructor = MyRouter;
_.extend(MyRouter.prototype, {
    route: function(route, name, callback) {
      if (!_.isRegExp(route)) route = this._routeToRegExp(route);
      if (!callback) callback = this[name];
      Backbone.history.route(route, _.bind(function(fragment) {
        var args = this._extractParameters(route, fragment);
        try {
            callback && callback.apply(this, args);
        }
        catch(e)
        {
            if (e instanceof RouteError)
                return this;
            else
                throw e;
        }
        this.trigger.apply(this, ['route:' + name].concat(args));
        Backbone.history.trigger('route', this, name, args);
      }, this));
      return this;
    },
});
var loadUrl = Backbone.History.prototype.loadUrl;
Backbone.History.prototype.loadUrl = function (fragmentOverride){
    try {
        loadUrl.apply(this, arguments);
    }
    catch (e){
        if (e instanceof RouteError)
            return ;
        else
            throw e;
    }

};
(我没有检查任何这些…)


所以我认为主干网不支持这一点…

在主干网中,我发现在路由之前/之后检查事情的唯一方法是扩展Router.route。感觉不是很干净,因为您必须从源代码复制和编辑,但这是我找到的唯一方法。在主干网默认代码(1.0.0)下方和注释之间显示您需要的自定义代码:

  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 custom code
    callback = _.wrap(callback, _.bind(function(cb) {
      console.log('before');
      _.bind(cb, this)();
      console.log('after');
    }, this));
    // finish 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
.bind
因此
这是您在使用路由器时所期望的。否则我会得到一个“这是未定义的”错误


现在你可以在你的路线开火之前/之后挂上你的支票。在受影响的路由器中,您可以加载视图并执行所需的任何操作。

谢谢您的回答,但是,我无法理解此扩展方法如何处理未配置为路由的url。此外,如果我实现了此功能,我想我需要检查尝试执行的路线的新viewmodel回调是否可以导航。恐怕我没有完全理解您的问题:-)