简体   繁体   中英

Advanced routing and single object definition?

I'm trying to simplify routes. What I have now still requires a reference inside the class that extends router, but since I'm using eval to instantiate references, every route method is the same .

Currently, inside my app:

ROUTES =
  'action1/:page': 'action1'
  'action2/:page': 'action2'
  '*path': 'default' # Default routes to action1

# Start Backbone history.
App.Router = new Routes(
  routes: ROUTES
)
App.Router.setDefaultRoute 'action1'
Backbone.history.start()

And the Router class:

class window.Routes extends Backbone.Marionette.AppRouter

  constructor: (options) ->

    @on 'all', @storeRoute
    @history = []
    super options

  @trace initialize: () ->

    debug.info 'Routes: ' + JSON.stringify @routes

  @trace setDefaultRoute: (route) ->

    App.Data.defaultRoute = route

  @trace getDefaultRoute: () ->

    App.Data.defaultRoute

  @trace storeRoute: () ->

    @history.push Backbone.history.fragment

  @trace getPrevious: () ->

    if @history.length > 1
      @history[@history.length - 1] 

  @trace getPreviousRoute: () ->

    @getPrevious().split('/')[0]

  @trace getPreviousPage: () ->

    @getPrevious().split('/')[1]

  @trace getFormattedWindowHash: () ->

    hash = window.location.hash
    hash = hash.substring(1, hash.length) 

    hash

  @trace getCurrentRoute: () ->

    current = @getFormattedWindowHash().split('/')[0]

    # Allow us to not specify 'route = <route>' inside every routing method.
    if !current
      current = @getDefaultRoute()
    else
      current = current

    current = current.charAt(0).toUpperCase() + current.slice(1)    

  @trace getCurrentPage: () ->

    @getFormattedWindowHash().split('/')[1]

  # Everytime a page is loaded, default data is cleared by instantiating new 
  # Views, Events, UI, State, and Error classes.
  @trace setupPage: (page) ->

    route = @getCurrentRoute()

    debug.info 'current route: ' + route

    event = 'App.Pages.Events.' + route + ' = new App.Events.' + route + '()'
    debug.info 'eval event: ' + event

    eval event

    # The magic which routes to the page.
    goTo = 'App.Pages.Events.' + route + '.router(parseInt(' + page + '))'
    debug.info 'goTo: ' + goTo

    eval goTo

  # Place routing actions below.

  @trace action1: (page) ->

    @setupPage page

  @trace action2: (page) ->

    @setupPage page

  # Default route.
  @trace default: () ->

    # TODO make this settable?
    @action1 1

What I want to do is be able to remove these 3 methods:

 @trace action1: (page) ->

    @setupPage page

  @trace action2: (page) ->

    @setupPage page

  # Default route.
  @trace default: () ->

    # TODO make this settable?
    @action1 1

How can I accomplish this?

Running: http://franklovecchio-playback.herokuapp.com/?log=true

Full code: https://github.com/franklovecchio/playback

You can get away with two route handlers:

ROUTES =
  'action1/:page': 'page'
  'action2/:page': 'page'
  '*path': 'def'

and then:

page: (page) ->
  @setupPage(parseInt(page, 10))
def: ->
  @setupPage(1)

The splat route ( *path ) will send the matched part of the route to the handler so you can't use just one route handler without attempting to interpret what the splat matches.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM