Передача параметров между маршрутами
Что такое "подходящий" способ в Ember для отправки параметра с одного маршрута на другой? Например, у меня есть два маршрута, определенные как таковые:
this.resource('activities', { path: '/activities/:on_date' }, function() {
this.route('new');
});
когда на ActivitiesRoute
пользователю предоставляется раскрывающийся список возможных действий. Когда они выбирают что-то, он переходит к ActivitiesNewRoute
:
this.transitionToRoute('activities.new');
и я знаю, что есть второй параметр, доступный в методе transitionToRoute(route,model)
, но он предназначен для передачи в модели, и я предполагаю, что это не должно быть перепрофилировано для другой передачи параметров. В этом случае выборка выбирает идентификатор модели Action
, а модель для 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, чтобы узнать, может ли это работать, но похоже на соглашение, так что это мой "плохой вариант".
Ответы
Ответ 1
Вы можете использовать API needs
(читайте об этом здесь):
App.ActivitiesNewController = Ember.ObjectController.extend({
needs: ['activities']
// Bind the property you need
actionTemplateBinding: 'controllers.activities.actionTemplate'
});
Так что вам действительно нужно передать параметр между контроллерами, что и есть для needs
. Кроме того, привязывая свойство с помощью needs
, вы убедитесь, что оно постоянно синхронизируется, вместо того чтобы полагаться на вызываемый setupController
.
Ответ 2
transitionTo
и transitionToRoute
возвращают объект, похожий на обещание. Параметр, с которым этот объект разрешен, - это маршрут, из которого вы можете получить доступ controller
и currentModel
. Таким образом, хороший чистый способ передачи информации на маршрут, к которому вы переходите, это:
var my_param = ....;
this.transitionToRoute('activities.new').then(function(newRoute) {
newRoute.currentModel.set('someProperty', my_param);
//or
newRoute.controller.set('someProperty', my_param);
});
ИЗМЕНИТЬ/RANT:
Обратите внимание, что в большинстве случаев вы хотите использовать needs
и связывать вещи между контроллерами. Однако, конечно, есть случаи, когда у вас есть вещи, которые зависят от логики перехода маршрута - например, контроллер B имеет состояние X, если мы пришли к маршруту A с маршрута B, но будем указывать Y, если мы пришли из routeC. В этом случае мой ответ ценен.
Первичное значение для сообщества разработчиков - это не непосредственные ответы, которые вы получаете на вопросы, которые вы публикуете, но массивное постоянно растущее богатство полезных знаний о развитии. Когда вы "выходите" из пользовательского вопроса, что они "должны" делать что-то другое, кроме того, что они спрашивают, как это сделать, вы можете быть правы (или вы просто не можете вообразить их конкретные обстоятельства), но если вы отвечаете только с вашей рекомендацией/правилом/афоризмом/load-cult-dictum вместо ответа на ФАКТИЧЕСКИЙ ВОПРОС, вы уменьшаете ценность всех остальных поисковых запросов Google. Если вы хотите сказать кому-то о чем-то другом, кроме того, что они задают, сделайте это в комментарии или в примечании к ответу на фактический вопрос.
Ответ 3
Вы можете использовать параметры запроса (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-адресу - поэтому оно не подходит для какой-либо важной информации, которую вы можете пройти между маршрутами.
Ответ 4
Я отвечу на свой вопрос тем, что я решил продолжить, но держите его открытым на несколько дней, чтобы узнать, вернется ли кто-нибудь с более опытным ответом. Мой ответ вполне может быть прекрасным... он все равно работает.
Я пошел с вариацией # 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'));
}
});
Все еще интересно услышать от людей, если есть лучший способ сделать это.
Ответ 5
Переход к маршруту с параметрами и заданной моделью
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