2013-11-15 20 views
9

voglio definire un percorso in emberjs, che ha un parametro opzionale esempio:ember.js - definire percorso con parametro opzionale e il modello predefinito

/video e /video/123

se non viene fornito alcun parametro , Voglio usare un modello/dispositivo di default. se viene fornito un parametro, allora voglio ovviamente cercare il modello usando il parametro.

se poi si passa a un altro percorso e si torna al percorso senza il parametro, si desidera utilizzare il modello precedentemente caricato.

esempio:

startup app

/video - mostra il mio default/apparecchio modello

/video/123 - mostra il modello 123

/another-route - mostra nuova rotta

/video - mostra il modello 123

è possibile?

risposta

5

C'è un modo pulito per fare questo, anche se è un po ' "difficile". L'idea è di usare una rotta nidificata per contenere l'id, ma non renderla, invece di avere la route madre responsabile del rendering usando l'helper di rendering. Quando lo fai in questo modo, tutta la logica può vivere in VideoChoiceController e verrà utilizzata per visualizzare il video predefinito o uno specifico. Quando lo fai in questo modo, non è necessario "ricordare" esplicitamente l'ultimo video, la macchina a stati che il motore del percorso rappresenta lo fa per te.

App.Router.map(function) { 
    this.resource('video', function(){ 
    this.route('choice', {path: ':video_id'}); 
    }); 
}); 

App.VideoRoute = Ember.Route.extend({ 
    model: function(params) { 
    return App.get('defaultVideo'); 
    }, 

    setupController: function(controller, model) { 
    var video_choice = this.controllerFor('video.choice') 

    // this is necessary if you want, for example, 
    // to display the name or a link to the default video 
    // when a specific video is being displayed 
    controller.set('model', model); 

    if(Ember.isEmpty(video_choice.get('model'))){ 
     video_choice.set('model', model); 
    } 
    } 
}); 

App.VideoChoiceRoute = Ember.Route.extend({ 
    model: function(params) { 
    return this.get('store').find('video', params.video_id); 
    }, 

    renderTemplate: function() { 
    // if you don't override renderTemplate to do nothing, 
    // everything will still work but you will get an assertion 
    // error that render should only be used once with a 
    // singleton controller 
    } 
}); 



<script type="text/x-handlebars"> 
    <div> 
    {{outlet}} 
    </div> 
</script> 

<script type="text/x-handlebars" data-template-name='video'> 
    <div> attrributes here always refer to the default video: {{name}} </div> 
    {{render "video.choice"}} 
</script> 

<script type="text/x-handlebars" data-template-name='video'> 
    <div> 
    attrributes here always refer to specific or last video, 
    or default if a specific video has never been loaded: {{name}} 
    </div> 
</script> 
+0

il motivo per cui mi riferisco a questo come leggermente complicato è che si basa sul fatto che cambiando rotte demolisce il vecchio modello di rotte ma non cancella il suo controller, una sfumatura che io Non sono sicuro che sia destinato a essere sfruttato. –

+3

c'è un altro modo per farlo, utilizzando il percorso del video/indice e facendo sì che il modello di video/indice faccia un '{{rendering 'video.choice' defaultVideo}}'. Quindi puoi rendere VideoChoiceRoute come normale. Questo potrebbe effettivamente essere migliore e meno "difficile". –

+0

ottimo, funziona perfettamente – kabal

0

Decisamente, dovrete fare qualcosa di un po 'strano, come la memorizzazione dell'ultimo video in alcune variabili globali, ma dipende da voi.

http://emberjs.jsbin.com/uhoQozu/1/edit

http://emberjs.jsbin.com/uhoQozu/1#/video

http://emberjs.jsbin.com/uhoQozu/1#/video/32

App.Router.map(function() { 
    this.resource('videoModel', {path:'/video/:video_id'}); 
    this.resource('video'); // this resource can be accessed at /video 
}); 
+0

stai lasciando fuori un sacco di cose che dovrà fare per farlo funzionare in questo modo, come specifiying quale template usare in 'renderTemplate', e la manipolazione la duplicazione tra la videoModel e controller video ecc –

+0

Una recensione della mia risposta sarebbe apprezzata, grazie – ppcano

5

ho finito per usare una soluzione diversa:

this.resource('video', function() { 
    this.route('index', {path: '/'}); 
    this.route('item', {path: ':id'}); 
    }); 

Questi supporto itinerari:

/video - mostra il mio default/apparecchio modello

/video/123 - mostra il modello 123

Quando l'utente accede a /video, VideoIndexRoute deve reindirizzare a VideoItemRoute senza alcun ID.

var VideoIndexRoute = Em.Route.extend({ 

    afterModel: function() { 

    // this is the tricky part 
    this.replaceWith('video.item', ''); 

    } 

}); 

Ora, il VideoItemRoute deve controllare se c'è qualche modello associato, e quando manca, dovrebbe utilizzare le attrezzature di default o uno nuovo.

var VideoItemRoute = Em.Route.extend({ 

    model: function(param) { 
    if (param.id) { 
     return this.store.find('video', param.id); 
    } 
    }, 

    setupController: function (controller, model) { 
    if (!model) { 
     model = this.store.createRecord('video',{ 
     name: 'default Name' 
     }); 
     // or use fixture... 
    } 
    this._super(controller, model); 

    } 

}); 
Problemi correlati