2013-04-11 10 views
10

Say Mam router sieci szkieletowej jak:Jak mogę uruchomić funkcję "middleware" przed wykonaniem metody route?

routes: 
    ""       : "homepage" 
    "catalog/:id"    : "catalogPage" 
    "catalog/:id/products/:id2" : "productPage" 

homepage :   -> doStuff() 
catalogPage: (id)  -> doOtherStuff() 
productPage: (id, id2) -> doEvenMoreStuff() 

i funkcję:

executeBefore = -> console.log("hello") 

Jeśli chcę executeBefore być wywoływany i wykonywany za każdym razem, gdy trasa jest o nazwie a przed odpowiedniej metody trasy czy istnieje prosty sposób, aby to zrobić oprócz wstawiania wywołania executeBefore na początku każdej metody trasy?

Odpowiedz

27

Można zastąpić funkcję route w swojej klasie routera do przechwytywania połączeń trasy:

var Router = Backbone.Router.extend({ 
    routes: { 
     "" : "homepage", 
     "catalog/:id" : "catalogPage" 
    }, 

    route: function(route, name, callback) { 
     var router = this; 
     if (!callback) callback = this[name]; 

     var f = function() { 
      console.log('route before', route); 
      callback.apply(router, arguments); 
      console.log('route after', route); 
     }; 
     return Backbone.Router.prototype.route.call(this, route, name, f); 
    }, 

    homepage: function() { 
     console.log("homepage"); 
    }, 
    catalogPage: function(id) { 
     console.log("catalogPage "+id); 
    } 
}); 

var r = new Router(); 
Backbone.history.start(); 

a demo http://jsfiddle.net/nikoshr/EdLzh/

+1

to rozwiązanie działa dobrze. Powiedział, że dokumenty odnoszą się do metody "wykonania", która powinna zapewniać podobną funkcjonalność (aczkolwiek w czasie wykonywania). Nie działa dla mnie - czy ktoś inny miał z tym szczęście? Http: //backbonejs.org/#Router-execute – som

-1

Można grać z wydarzeniami:

Backbone.history.on('route', function() { 
    // Do your stuff here. 
    executeBefore(); 
}); 

odwiedzenie # help/uploading uruchomi trasę: help event from the router.

Najwyraźniej ten będzie uruchamiany przed przekierowaniem:

https://github.com/documentcloud/backbone/blob/master/backbone.js#L1243

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); 
}); 
+0

Myślę, że twoja odpowiedź jest błędna, ponieważ jeśli używasz routera Backbone przez wywołanie router.navigate (trasa, opcje); najpierw wykona wywołanie zwrotne trasy i wywołanie zwrotne "route" zdarzenia. Testowałem to sam. Przepraszam, że nie zapewniłem skrzypiec. – bboydflo

2

można również użyć backbone.routefilter wtyczki.

będziesz mógł ustawić filtr dla wszystkich tras

var Router = Backbone.Router.extend({ 
    routes: { 
    "": "index", 
    "page/:id": "page" 
    }, 
    before: function(route, params) { ... }, 
    after: function(route, params) { ... }, 
    index: function(){ ... }, 
    page: function(route){ ... } 
}); 

Albo wybrać kilka tras

var Router = Backbone.Router.extend({ 
    routes: { 
    "": "index", 
    "page/:id": "page" 
    }, 
    before: { 
    "": function(route) { ... }, 
    "page/:id": function(route) { ... } 
    }, 
    after: function(route) { ... }, 
    index: function(){ ... }, 
    page: function(route){ ... } 
}); 
3

Od lutego, 13, 2014, można użyć router.execute(callback, args, name) (http://backbonejs.org/#Router-execute) dla tego .

Więc przechwytujących będzie wyglądał mniej więcej tak to

routes: { 
    '': 'homepage', 
    'catalog/:id': 'catalogPage', 
    'catalog/:id/products/:id2': 'productPage' 
}, 
execute: function(callback, args, name) { 
    // Do your stuff here 
    executeBefore(); 

    if (callback) callback.apply(this, args); 
} 

https://github.com/jashkenas/backbone/commit/791033dc1aab53e9e5c9366f64a854224f851231

Powiązane problemy