2013-11-15 5 views
9

オプションのパラメータとデフォルトモデルとルート定義:ember.js - 例えばオプションのパラメータがある私はemberjsでルートを定義したい

/video/video/123

は何のパラメータが提供されていない場合を、私はデフォルトモデル/フィクスチャを使用したいと思います。 パラメータが指定されている場合は、パラメータを使用してモデルを明示的に参照する必要があります。

私は別のルートに移動し、パラメータなしでルートに戻る場合は、以前に読み込まれたモデルを使用します。

例:

startup app

/video -

/video/123私のデフォルト/フィクスチャのモデルを示している - ショーモデル123

/another-route -

/video新しいルートを示して - ショーモデル123

これは可能ですか?

答えて

5

それは少し "トリッキー" ですが、これを行うにはきれいな方法は、あります。アイデアは、IDを保持するネストされたルートを使用するが、レンダリングヘルパーを使用して親ルートをレンダリングする代わりに、親ルートを使用することです。このようにすると、すべてのロジックがVideoChoiceControllerに保存され、デフォルトのビデオまたは特定のビデオを表示するために使用されます。このようにすると、最後のビデオを明示的に「記憶」する必要はなく、ルートエンジンが表すステータスマシンがあなたのために行います。

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

私はこれを少し厄介であると言います理由は、ルートを変更すると古いルートテンプレートが壊れてしまいますが、コントローラをクリアしないというニュアンスです。悪用されることは確実ではない。 –

+3

これを行うには、ビデオ/インデックスルートを使用し、ビデオ/インデックステンプレートに '{{render 'video.choice' defaultVideo}}'を実行する別の方法があります。その後、通常どおりVideoChoiceRouteをレンダリングすることができます。これは、実際にはより良い&少ない "トリッキー"かもしれません。 –

+0

偉大な、これは完全に動作します – kabal

0

間違いなく、最終的なビデオをいくつかのグローバル変数に保存するなど、ちょっとファンキーなことをする必要がありますが、それはあなた次第です。

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

。 –

+0

私の応答のレビューはありがたいです、ありがとう – ppcano

5

私は別の解決策使用して終了:これらのルートのサポート

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

を:

/videoは -

/video/123私のデフォルト/フィクスチャのモデルを示している - ショーモデル123

へのユーザーアクセスでは、VideoIndexRouteはIDなしでVideoItemRouteにリダイレクトする必要があります。今

var VideoIndexRoute = Em.Route.extend({ 

    afterModel: function() { 

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

    } 

}); 

関連するすべてのモデルが存在する場合、VideoItemRouteは確認する必要があり、それが欠けているとき、それはデフォルトの備品や新しいものを使用する必要があります。あなたは `renderTemplate`でレンダリングするテンプレートspecifiyingのように、彼はそれがこのように動作させるために行う必要があるでしょう多くのものを残し、そしてvideoModelとビデオコントローラなどの間の重複を処理している

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); 

    } 

}); 
関連する問題