1
votes

I try to study and use Backbone/Marionette in my project. Now I stuck with Router navigation which work not as I though it should.

class MyApp.Router extends Marionette.AppRouter
    appRoutes :
        'info/:place/(:what)' : 'places_page'

MyApp.Controller = ->
    places_page: (place,what)->
        console.log 'Triggered places_page'


MyApp.addInitializer( ->
    controller = new MyApp.Controller()
    new MyApp.Router
        controller: controller
    Backbone.history.start( pushState: false )
    )


MyApp.vent.on('do:search', ->
    console.log 'triggered do:search'
    place = 'Moscow'
    what = 'Пицца'
    info_model.set place: place, item:what
    new_url = 'info/'+where+'/'+what
    if new_url != decodeURIComponent(Backbone.history.fragment)
        Backbone.history.navigate(new_url, {trigger: false})

On initial load of site.com/#info/Budapest/Vine page or reload it, I get Triggered places_page message as I expect.

But when I fire do:search event which update url to site.com/#info/Moscow/Пицца, I get Triggered places_page again! So it reload all my views from scratch instead of just change url and re-render one model.

What I can do wrong here?

Update 2: Found strange thing. If I use latin letters in new url, everything work like it should. But if I use cyrillic in new url path, it will trigger route function.

Backbone: 1.0, Marionette:v1.0.3, jquery: 1.9.1

3
How are you initialize your Backbone.History ? - Ivan Antropov
Backbone.history.start( pushState: false ) , if I understand you correctly - Ilya

3 Answers

4
votes

Mystery solved!

That happens because of non-latin symbols in url. Correct code:

new_url = 'info/'+encodeURIComponent(where)+'/'+encodeURIComponent(what)
if new_url != Backbone.history.fragment
    Backbone.history.navigate(new_url, {trigger: false})

Because Backboune.navigate don't execute navigate if url didn't change and trigger is false by default, I can write it simple like that:

new_url = 'info/'+encodeURIComponent(where)+'/'+encodeURIComponent(what)
Backbone.history.navigate(new_url)
0
votes

Backbone.history takes an object when starting. Try this syntax in CoffeeScript:

Backbone.history.start
  pushState: false

In addition, pushState is false by default, so you can just have Backbone.history.start()

Does this solve your issue?

0
votes

Proper URL encoding is required. I couldn't find this in the docs of Backbone related to the router functionality.

I had the same issue, alas with spaces in the query part, i.e.:

#app/terms?filter=java ee

Together with the encodeURIComponent solution as described in your answer, I also found the following lines of comments in backbone.js (1.0.0), pertaining to the navigate function:

// Save a fragment into the hash history, or replace the URL state if the
// 'replace' option is passed. You are responsible for properly URL-encoding
// the fragment in advance.