Эмбер, передавая модель для перехода ToRoute
Я использую Ember-Cli с Ember 1.11
Я пытаюсь использовать метод transitionToRoute в контроллере для перехода к маршруту и подачи его динамически сгенерированного объекта в качестве модели.
Вот мой контроллер:
import Ember from 'ember';
export default Ember.Controller.extend({
actions: {
launch_scanner: function(){
console.log('launch_scanner');
var model = {name: "Edward", phone: "123", email: "email@test.com"};
//the final app will pull the model variable from a QR scanner
this.transitionToRoute('addcontact', model);
}
}
});
Когда я запускаю это действие, метод transitionToRoute вызывает эту ошибку:
Uncaught Error: передано больше объектов контекста, чем динамических сегментов для маршрута: addcontact
Если я опускаю параметр модели, он просто переходит на маршрут addcontact. Что я делаю неправильно?
Вот мой файл роутера:
import Ember from 'ember';
import config from './config/environment';
var Router = Ember.Router.extend({
location: config.locationType
});
Router.map(function() {
this.route('home', {path: '/'});
this.resource('addcontact', {path: '/addcontact'});
});
export default Router;
3 ответа
Вы имеете дело с классической проблемой, возникающей во многих приложениях Ember, которая заключается в том, как обрабатывать "новые"/"создавать" ситуации.
Вы не можете определить маршрут, такой как
this.route('addcontact', { path: /addcontact/:thing_id }
потому что новый контакт не имеет идентификатора, и не будет, пока он не будет сохранен на сервере, после чего он больше не будет новым.
Тем не менее, в вашем приложении есть некоторый момент, в вашем случае, я полагаю, на "домашней" странице, где пользователь нажал кнопку "Новый контакт", и она может содержать полезную информацию о том, что создавать или как ее создавать, и может даже хотите создать объект прямо там, используя this.store.createRecord
- как передать эту информацию или новую запись addcontacdt
маршрут, который может не иметь динамического отрезка?
Некоторые идеи включают в себя:
Создайте новый контакт в вашем
home
маршрут или что-то еще, и сохранить его в контроллере. Затем вmodel
крюк нового маршрута, получить его с помощьюthis.controllerFor('home').get('newContact')
,Передайте необходимые параметры для создания нового объекта, если таковые имеются,
addcontact
маршрут в качестве параметров запроса, используяtransitionTo('newcontact', queryParameters)
, Затем вmodel
крюк, создайте новый объект, используяthis.store.createRecord('contact', transition.queryParameters)
или что-то эквивалентное.
Если вы хотите перейти к подгруппе для несохраненной записи, у вас есть 2 варианта
Либо сохраните свою модель перед переходом на маршрут
model.save().then(function(result){
self.transitionToRoute('route',result.id)
});
или сгенерируйте идентификатор для модели в createRecord, если вы не хотите сохранять модель (возможно, пользователь может отменить, а вы не хотите обрабатывать удаление)
Основная функция для создания идентификатора с низким потенциалом идентичных идентификаторов будет:
generateIdForRecord: function() {
var d = new Date().getTime();
var uuid = 'xxxxyyyxxxxxxxxyyxyxxxyyy'.replace(/[xy]/g, function(c){
var r = (d + Math.random() * 16) % 16 | 0;
d = Math.floor(d / 16);
return (c === 'x' ? r : (r & 0x7 | 0x8)).toString(16);
});
return uuid;
}
Используя этот подход, еще не сохраненная модель имеет идентификатор для перехода, просто подумайте об обработке переходов с этого маршрута, поскольку текущий идентификатор больше не действителен после сохранения модели (модель получает реальный идентификатор с сервера в ответ).
Это нормально, потому что у вас нет динамического сегмента в вашем маршруте addContact. Вы должны изменить свой маршрутизатор на
Router.map(function() {
this.route('home', {path: '/'});
this.resource('addcontact', {path: '/addcontact/:id'});
});
Теперь вы можете передать идентификатор модели вместо всей модели, чтобы вызвать model
крюк. В качестве альтернативы вы можете передать всю модель, но это не вызовет model
крюк. Хотя вы все еще можете изменить свою модель в afterModel
крюк.