se você tiver um controlador definido como
App.IndexController = Ember.Controller.extend({
queryParams: ['foo'],
foo: ''
});
e no SetupController de Rotas você faz algo como ...
setupController: function(controller, model){
controller.set('model', model);
controller.set('foo', 'bar'); // <-- setting this should update the query param
}
O parâmetro de consulta não é definido no url.
Você pode ver uma caixa de trabalho aqui: http://emberjs.jsbin.com/dekuj/1/edit
Corrigido com Ember.run.later
(para garantir que as coisas tenham se materializado totalmente primeiro): http://emberjs.jsbin.com/kowoqo/1/edit
@machty - Qual é o comportamento esperado aqui?
Achei que tínhamos testes explícitos para esta ... verificação.
Acho que é um bug ... temos testes para isso, mas apenas no contexto de transitionTo
e não na inicialização inicial do aplicativo.
trabalhando: http://jsbin.com/mejeto/1#/about
Eu adicionei um teste de falha para este bug https://github.com/emberjs/ember.js/pull/5473
Tentaremos tentar consertar isso
Acho que me deparei com um problema relacionado, então não tenho certeza se precisa de um tíquete separado aqui no GitHub.
export default Ember.Controller.extend({
queryParams: ['modal'],
modal: null,
handleModal: function () {
this.send('openModal', this.get('modal'));
}.observes('modal')
});
export default Ember.Route.extend({
actions: {
openModal: function (name) {
return this.render(name, {
into: 'application',
outlet: 'modal'
});
}
}
});
Isso funciona em todos os casos, exceto na inicialização, quando lança Error while processing route: index Nothing handled the action 'openModal'. If you did handle the action, this error can be caused by returning true from an action handler in a controller, causing the action to bubble.
Pode ser corrigido usando Ember.run.next
handleModal: function () {
Ember.run.next(this, function () {
this.send('openModal', this.get('modal'));
});
}.observes('modal')
embora pareça errado.
JSBins:
Sem Ember.run.next gera erro
Com Ember.run.next imprime 'redered' no console
@ Igor10k Estou enfrentando exatamente o mesmo problema, modal e tudo. Envolvê-lo em Ember.run.next corrige o problema, mas parece errado para mim também.
Alguém pode confirmar que isso ainda é um problema no 1.8?
@wagenet sim, isso ainda é um problema no 1.8:
http://emberjs.jsbin.com/lezuhu/1/edit?html , js, output
e canário:
http://emberjs.jsbin.com/doyohe/1/edit?html , js, output
@machty - Pensamentos?
Eu acho que isso também é um bug para mim usando 1.8.1. O que eu quero fazer é chamar um método especial no meu controlador toda vez que um queryParam específico muda. Eu tenho um roteador parecido com este.
Algum conselho?
// ...snip...
// for pagination
queryParams: {
offset: {
refreshModel: true
}
},
model: function(params) {
// returns model
},
setupController: function(controller, model) {
this._super(controller, model);
controller.set('model', model);
// Fetch results is a method that does a bunch work
// sets up some filters, generates a promise, resolves that promise
// and then sets some array data on the controller once promise resolves.
// offset is a pagination feature which determines which specific results
// are fetched. I would like to be able to call fetchResults everytime the
// offset queryParam is changed.
Ember.run.later(function() {
controller.sendAction('fetchResults');
})
}
// ...snip...
@machty - Idéias sobre por onde começar a cavar nisso?
Estou tendo o mesmo problema. this.set () no controlador não atualizará o parâmetro de consulta na URL
App.SearchController = Ember.Controller.extend ({
queryParams: ['domínio'],
domínio: nulo,
domainField: Ember.computed.oneWay ('domínio'),
ações: {
searchSubmit: function () {
this.set ('domínio', this.get ('domainField')); // Isso define o parâmetro 'domínio', mas não modifica o URL. Portanto, o modelo em App.SearchRoute nunca é chamado como esperado
}
},
});
App.SearchRoute = Ember.Route.extend ({
queryParams: {
domínio: {
refreshModel: true // Opte pela transição completa
},
},
modelo: função (params) {
var domain = params.queryParams.domain;
return $.getJSON('/search?domain=usv.com&name=').then(function(resp){
console.log(resp);
return resp.data;
});
},
ações: {
atualizar: function () {
Ember.Logger.log ('A rota agora está atualizando ...');
this.refresh ();
}
},
});
Você pode fornecer uma solução nesse ínterim?
Para esclarecer: this.set () em meu código fará a alteração no objeto Class, mas não altera o URL de forma alguma
Isso é antigo, mas parece que ainda é um problema? Não consigo descobrir as circunstâncias, mas periodicamente quando tento definir um parâmetro de consulta do controlador, ele não se propaga para a URL. Posso verificar o valor da propriedade no controlador e está definido corretamente, mas a URL não mudou. Tentei usar um Ember.run.next
sem sucesso. Ai!
Enfrentando esse problema também
@rwjblue : Existe alguma atualização sobre isso?
Qualquer atualização? Aqui, mesmo ao alterar o valor do controlador, a url é atualizada por alguns ms e volta ao valor antigo, mesmo que o controlador tenha o novo valor na variável
Aqui está uma solução alternativa:
No controlador, adicione um observador que altere o parâmetro de consulta no próximo ciclo de execução após ter sido definido. Neste exemplo, eu queria remover o parâmetro de consulta token
da URL e essa abordagem funciona bem.
import Ember from 'ember';
export default Ember.Controller.extend({
queryParams: ['token'],
token: null,
unsetToken: Ember.observer('token', function() {
if (this.get('token')) {
Ember.run.next(this, function() {
this.set('token', null);
});
}
}),
});
Acabei de encontrar isso hoje, quando tentei definir um parâmetro de consulta do setupController na inicialização. run.next parece uma solução alternativa, mas acho que a solução adequada seria ter 2 rotas e, na inicialização, a primeira rota faria a segunda rota de transição para o valor do parâmetro de consulta.
Ember 2.8
Marcando o problema como inativo de acordo com nossa política de triagem .
Eu também estou vendo esse problema no Ember 2.11, tentar limpar um parâmetro de consulta no controlador não tem efeito. A solução alternativa de @barelyknown me leva a maior parte do caminho, mas ainda consideraria isso um bug aberto.
EDIT: Ignore todo esse jazz. Há algumas informações ruins / erradas aqui, e @locks me indicou uma solução muito melhor - com um parâmetro de consulta em vez de um segmento dinâmico - imediatamente abaixo. Ele vincula o parâmetro de consulta a uma propriedade normal com uma propriedade de sombra computada que limpa e define get
(minhas tentativas anteriores envolveram vincular o parâmetro de consulta a uma propriedade computada que higienizou e configurou set
) . Desculpe pelo barulho!
A melhor solução ...
// app/router.js
Router.map(function() {
this.route('shop');
});
// app/routes/shop.js
export default Ember.Route.extend({
queryParams: {
_selectedItemIndex: {
replace: true
}
}
});
// app/controllers/shop.js
import computed from 'ember-macro-helpers/computed';
export default Ember.Controller.extend({
cart: Ember.service.inject(),
queryParams: {
_selectedItemIndex: 'i'
},
_selectedItemIndex: 0,
selectedItemIndex: computed('_selectedItemIndex', {
get(index) {
const itemsLength = this.get('cart.items.length');
if (isNaN(index) || index < 0 || index >= itemsLength) {
index = 0;
}
return this.set('_selectedItemIndex', index);
},
set(index) {
return this.set('_selectedItemIndex', index);
}
})
});
O problema original e a solução ...
Perdi a maior parte de ontem para esse problema que ainda persiste na versão 2.14-beta. Meu caso de uso é higienizar um parâmetro de consulta para usar como índice em um Ember.Array. Se estiver malformado (por exemplo, NaN ou uma string) e / ou fora dos limites, ele deve usar um índice padrão e atualizar o URL para refletir o ajuste (para que os eventos em resposta a cliques futuros sejam acionados de forma adequada - posso explicar isso mais adiante para ajudar a demonstrar que este não é apenas um problema cosmético).
Não consigo definir a propriedade de setupController()
pois ela não atualiza o URL (conforme descrito neste problema). Não posso defini-lo no próximo tick usando Ember.run porque isso terá efeito muito tarde (ou seja, um índice inválido já teria sido usado para acessar o array). Não posso defini-lo uma vez e, em seguida, defini-lo novamente no próximo tique para atualizar o URL porque não há nenhuma alteração de propriedade (ou pelo menos é o que eu suspeito que seja o motivo pelo qual não funciona).
Não posso usar uma propriedade computada com um setter de higienização no controlador porque você não pode vincular um parâmetro de consulta a uma propriedade computada. Não posso usar um observador em uma propriedade normal porque você não pode definir a propriedade que está observando. Não posso usar um observador com Ember.run devido ao problema descrito acima.
Não posso chamar this.transitionTo({ queryParams: .. })
de setupController()
ou o gancho beforeModel()
ou controller.transitionToRoute({ queryParams: .. })
de setupController()
devido a # 14606 e problemas relacionados. Não posso definir refreshModel
para true
para o parâmetro de consulta porque outras coisas estão acontecendo no gancho model()
que não deve ser repetido se esse parâmetro de consulta mudar.
É evidente que existe um nexo de dor aqui. Esse problema, o número 14606, e a limitação de não ser capaz de vincular um parâmetro de consulta a uma propriedade computada se combinam para criar uma armadilha simples e frustrante.
Esta é minha solução alternativa: criei uma rota "selecionar" aninhada que simplesmente pega o parâmetro de consulta (ou - como no código abaixo - um segmento dinâmico), limpa-o e define a propriedade em seu controlador pai. Se o índice higienizado estiver fora dos limites, ele fará a transição para a rota de índice aninhada, que por sua vez fará a transição de volta para a rota de seleção aninhada com o índice padrão. As rotas aninhadas não têm modelos ou controladores e a rota pai não tem saída; eles existem apenas para lidar com esse problema de roteamento.
// app/router.js
Router.map(function() {
this.route('shop', function() {
this.route('index', { path: '/' });
this.route('select', { path: '/:index' });
});
});
// app/routes/shop.js
export default Ember.Route.extend({
setupController(controller, model) {
this._super(...arguments);
// some logic to set up the cart service
},
model() {
// fetch products to shop
}
});
// app/controllers/shop.js
export default Ember.Controller.extend({
cart: Ember.service.inject(),
selectedItemIndex: 0,
actions: {
selectItem(index) {
return this.replaceRoute('shop.select', index);
}
}
});
// app/routes/shop/index.js
export default Ember.Route.extend({
beforeModel() {
return this.replaceWith('shop.select', 0);
}
});
// app/routes/shop/select.js
export default Ember.Route.extend({
setupController(_, { index }) {
this._super(...arguments);
const
parentController = this.controllerFor('shop'),
itemsLength = parentController.get('cart.items.length');
index = parseInt(index, 10);
if (Number.isNaN(index) || index < 0 || index >= itemsLength) {
return this.replaceWith('shop.index');
}
parentController.set('selectedItemIndex', index);
},
model: _ => _
});
@mwpastore obrigado pela atualização, vamos encerrar isso. Tenha um ótimo fim de semana!
@locks se você quiser, reabra um problema de documentação para observar isso no setupController
(veja as notas nos menus suspensos por
@mwpastore Parece que poderíamos continuar com uma postagem no fórum em https://discuss.emberjs.com/ com sua solução
Esperar até que esse problema seja resolvido com uma solução alternativa para contornar o bug que ele relata e essa solução envolve definir uma propriedade em um getter computado?
Estou curioso para saber se há atualizações sobre isso.
Estou usando Ember.run.next
dentro da rota setupController
Comentários muito úteis
Eu também estou vendo esse problema no Ember 2.11, tentar limpar um parâmetro de consulta no controlador não tem efeito. A solução alternativa de @barelyknown me leva a maior parte do caminho, mas ainda consideraria isso um bug aberto.