在路由之间传递参数

时间:2013-09-30 16:10:57

标签: ember.js

Ember将参数从一条路线发送到另一条路线的“适当”方式是什么?例如,我有两条路由定义如下:

this.resource('activities', { path: '/activities/:on_date' }, function() {
    this.route('new');
});

ActivitiesRoute上,向用户显示可能的活动下拉列表。当他们选择某些内容时,会转换为ActivitiesNewRoute

this.transitionToRoute('activities.new');

并且我知道transitionToRoute(route,model)方法中有第二个参数可用,但它用于传入模型,我假设不应该将其重新用于其他参数传递。在这种情况下,下拉选项是选择Action模型ID,而ActivitiesNew的模型是Activity

以下是我对可行方法的三种猜测:

1)将其设为路由器参数

我想我可以更改ActivitiesNew以包含“参数”作为路线的一部分:

this.route('new', { path: '/new/:my_parameter' });

我不确定我是否真的希望它成为URL路径的一部分,但如果这是普遍的惯例,那么我就会接受它。

2)获得句柄,转换后

在transitionToRoute调用之后,我可以立即设置新控制器类的属性。不确定控制器是否会安装但我想象的是:

this.transitionToRoute('activities.new');
this.get('target').controllerFor('activities.new').set('my_parameter', myValue);

3)使用模型参数

this.transitionToRoute('activities.new',myValue);

我怀疑这是一个重要的禁忌。我没有查看Ember代码,知道这是否可行,但似乎违反惯例,所以这是我的“糟糕选择”。

5 个答案:

答案 0 :(得分:46)

transitionTo& transitionToRoute返回一个“类似承诺”的对象。解析此对象的参数是路径,您可以从中访问controllercurrentModel。因此,将信息传递到您要转换到的路径的一种很好的干净方法是:

var my_param = ....;
this.transitionToRoute('activities.new').then(function(newRoute) {
  newRoute.currentModel.set('someProperty', my_param);
  //or
  newRoute.controller.set('someProperty', my_param);
});

EDIT / RANT:

请注意,在大多数情况下,您确实希望使用needs,并在控制器之间绑定内容。然而,当然你有一些事情依赖于路由转换的逻辑 - 例如,如果我们从routeB来到routeA,则controllerB具有状态X,但是如果我们来自routeC则是状态Y.在那种情况下,我的回答是有价值的。

堆栈溢出到开发社区的主要价值不是你发布的问题的直接答案,而是大量不断增长的可谷歌开发知识。当你从一个用户的问题“推断”他们“应该”做的事情不是他们要求做的事情时,你可能是对的(或者你可能只是无法想象他们的特定情况),但是如果你只回答使用您的推荐/规则/格言/货物崇拜 - 格言而不是回答实际问题,您减少了其他人的谷歌搜索的价值。如果你想告诉别人做他们所要求的事情,可以在评论中或在实际问题答案的脚注中进行。

答案 1 :(得分:6)

您可以使用needs API(阅读相关here):

App.ActivitiesNewController = Ember.ObjectController.extend({
  needs: ['activities']

  // Bind the property you need
  actionTemplateBinding: 'controllers.activities.actionTemplate'
});

所以你真正需要的是在控制器之间传递一个参数,这正是needs的用途。另外,使用needs绑定该属性可确保它始终保持同步,而不是依赖于setupController被调用。

答案 2 :(得分:3)

您可以使用query-params(http://guides.emberjs.com/v1.10.0/routing/query-params/),如下所示:

this.transitionToRoute('activities.new', {queryParams: {my_param: 'my_value'});

为了能够在my_param控制器中接收new,您还需要定义以下行:

App.ActivitiesNewController = Ember.ObjectController.extend({
    queryParams: ['my_param'],
    my_param: ''
    ...
});

此解决方案的一个缺点是my_param的值将在URL中序列化 - 因此它不适合您可能希望在路由之间传递的某些敏感信息。

答案 3 :(得分:0)

我会用我现在决定使用的内容回答我的问题,但请保持开放状态几天,以确定是否有人回复了更有经验的答案。我的回答可能非常好......无论如何它都有效。

我从问题中找到了#2 的变体。不同之处在于,不是试图在ActivitiesNew控制器中设置Activities控制器中的属性,而是反过来:

ActivitiesNewRoute

App.ActivitiesNewRoute = Ember.Route.extend({
    model: function(params) {
        return this.store.createRecord('activity');
    },
    setupController: function(controller,model) {
        controller.set('actionTemplate', this.controllerFor('activities').get('actionTemplate'));
    }
});

如果有更好的方法,仍然有兴趣听取人们的意见。

答案 4 :(得分:0)

使用params转换到路线并设置模型

yourAction:->
    model = 'your-model'
    route = 'your.path.to.toute'
    routeLoad = @transitionToRoute route,
        id: model.get 'id'
    routeLoad.then (route) ->
        route.set 'controller.model', model
    return