Ember.js: establecer una propiedad de controlador en `setupController` no actualiza el parámetro de consulta

Creado en 21 ago. 2014  ·  29Comentarios  ·  Fuente: emberjs/ember.js

si tiene un controlador definido como

App.IndexController = Ember.Controller.extend({
  queryParams: ['foo'],
  foo: ''
});

y en Routes setupController haces algo como ...

setupController: function(controller, model){
  controller.set('model', model);
  controller.set('foo', 'bar'); // <-- setting this should update the query param
}

El parámetro de consulta no se establece en la URL.

Puede ver un contenedor de trabajo aquí: http://emberjs.jsbin.com/dekuj/1/edit

Bug Inactive Query Params

Comentario más útil

Yo también estoy viendo este problema en Ember 2.11, intentar borrar un parámetro de consulta en el controlador no tiene ningún efecto, la solución alternativa de @barelyknown me lleva a la mayor parte del camino, pero aún lo consideraría un error abierto.

Todos 29 comentarios

Se corrigió con un Ember.run.later (para asegurarse de que las cosas se hayan materializado completamente primero): http://emberjs.jsbin.com/kowoqo/1/edit

@machty - ¿Cuál es el comportamiento esperado aquí?

Pensé que teníamos pruebas explícitas para esta ... comprobación.

Creo que esto es un error ... tenemos pruebas para esto, pero solo en el contexto de transitionTo y no en el arranque inicial de la aplicación.

trabajando: http://jsbin.com/mejeto/1#/about

He añadido una prueba fallida para este error https://github.com/emberjs/ember.js/pull/5473
Intentaré intentar arreglar esto

Creo que me topé con un problema relacionado, por lo que no estoy seguro de si necesita un boleto separado aquí en 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'
            });
        }
    }
});

Esto funciona en todos los casos además del arranque cuando arroja 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.

Se puede arreglar usando Ember.run.next

handleModal: function () {
    Ember.run.next(this, function () {
        this.send('openModal', this.get('modal'));
    });
}.observes('modal')

aunque se siente mal.

JSBins:
Sin Ember.run.next arroja error
Con Ember.run.next imprime 'redered' en la consola

@ Igor10k Me estoy encontrando exactamente con este mismo problema, modal y todo. Envolverlo en Ember.run.next lo soluciona, pero también me parece mal.

¿Alguien puede confirmar que esto sigue siendo un problema en 1.8?

@wagenet sí, esto sigue siendo un problema en 1.8:
http://emberjs.jsbin.com/lezuhu/1/edit?html , js, salida

y canario:
http://emberjs.jsbin.com/doyohe/1/edit?html , js, salida

@machty - ¿Pensamientos?

Creo que esto también es un error para mí al usar 1.8.1. Lo que quiero hacer es llamar a un método especial en mi controlador cada vez que cambia un queryParam específico. Tengo un enrutador que se parece a esto.
¿Algún consejo?

// ...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 - ¿Ideas sobre dónde empezar a investigar esto?

Estoy teniendo el mismo problema. this.set () en el controlador no actualizará el parámetro de consulta en la URL

App.SearchController = Ember.Controller.extend ({
queryParams: ['dominio'],
dominio: nulo,

domainField: Ember.computed.oneWay ('dominio'),
acciones: {
searchSubmit: function () {
this.set ('dominio', this.get ('domainField')); // Esto establece el parámetro 'dominio' pero no modifica la URL. Entonces, el modelo en App.SearchRoute nunca se llama como se esperaba
}
},
});

App.SearchRoute = Ember.Route.extend ({
queryParams: {
dominio: {
refreshModel: true // Optar por la transición completa
},

},
modelo: función (parámetros) {
var dominio = params.queryParams.domain;

  return $.getJSON('/search?domain=usv.com&name=').then(function(resp){
  console.log(resp);
  return resp.data;
});

},
acciones: {
actualizar: función () {
Ember.Logger.log ('La ruta ahora se está actualizando ...');
this.refresh ();
}
},
});

¿Puede proporcionar una solución mientras tanto?

Para aclarar: this.set () en mi código hará el cambio en el objeto Class, pero no cambia la URL en absoluto

Esto es antiguo, pero parece que sigue siendo un problema. No puedo entender las circunstancias, pero periódicamente, cuando trato de establecer un parámetro de consulta desde el controlador, no se propaga a la URL. Puedo verificar el valor de la propiedad en el controlador y está configurado correctamente, pero la URL no ha cambiado. Intenté usar un Ember.run.next sin éxito. ¡Aflicción!

Experimentando este problema también

@rwjblue : ¿Hay alguna actualización sobre esto?

¿Cualquier actualización? Aquí, incluso cuando se cambia el valor del controlador, la URL se actualiza durante un par de ms y vuelve al valor anterior, incluso si el controlador tiene el nuevo valor en la variable

Aquí tienes una solución alternativa:

En el controlador, agregue un observador que cambie el parámetro de consulta en el siguiente ciclo de ejecución después de que se haya establecido. En este ejemplo, quería eliminar el parámetro de consulta token de la URL y este enfoque funciona bien.

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

Me encontré con esto hoy, cuando intenté establecer un parámetro de consulta desde setupController en el arranque. run.next parece una solución alternativa, pero creo que la solución adecuada sería tener 2 rutas y, en el arranque, la primera ruta haría la transición a la segunda ruta con el valor del parámetro de consulta.

Ember 2.8

Marcar el problema como inactivo según nuestra política de clasificación .

Yo también estoy viendo este problema en Ember 2.11, intentar borrar un parámetro de consulta en el controlador no tiene ningún efecto, la solución alternativa de @barelyknown me lleva a la mayor parte del camino, pero aún lo consideraría un error abierto.

EDITAR: Ignora todo este jazz. Aquí hay información incorrecta o incorrecta, y @locks me indicó una solución mucho mejor, con un parámetro de consulta en lugar de un segmento dinámico, en línea inmediatamente debajo. Vincula el parámetro de consulta a una propiedad normal con una propiedad calculada de sombra que desinfecta y establece en get (mis intentos anteriores implicaron vincular el parámetro de consulta a una propiedad calculada que desinfectó y estableció en set ) . ¡Perdón por el ruido!


La mejor solución ...

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


El problema original y la solución ...

Perdí la mayor parte de ayer por este problema que aún persiste en 2.14-beta. Mi caso de uso es desinfectar un parámetro de consulta para usarlo como índice en un Ember.Array. Si tiene un formato incorrecto (p. Ej., NaN o una cadena) y / o está fuera de los límites, debe usar un índice predeterminado y actualizar la URL para reflejar el ajuste (de modo que los eventos en respuesta a clics futuros se activen de manera adecuada; puedo explicar esto más adelante ayudar a argumentar que esto no es meramente una cuestión cosmética).

No puedo configurar la propiedad desde setupController() porque no actualiza la URL (como se describe en este problema). No puedo configurarlo en el siguiente tick usando Ember.run porque eso entrará en vigencia demasiado tarde (es decir, un índice no válido ya se habría usado para acceder a la matriz). No puedo configurarlo una vez y luego configurarlo nuevamente en el siguiente tick para actualizar la URL porque no hay cambio de propiedad (o al menos eso es lo que sospecho que es la razón por la que no funciona).

No puedo usar una propiedad calculada con un setter de desinfección en el controlador porque no puede vincular un parámetro de consulta a una propiedad calculada. No puedo usar un observador en una propiedad normal porque no puede establecer la propiedad que está observando. No puedo usar un observador con Ember.run debido al problema descrito anteriormente.

No puedo llamar this.transitionTo({ queryParams: .. }) desde setupController() o el gancho beforeModel() o controller.transitionToRoute({ queryParams: .. }) desde setupController() debido a # 14606 y problemas relacionados. No puedo establecer refreshModel en true para el parámetro de consulta porque están sucediendo otras cosas en el gancho model() que no deberían repetirse si este parámetro de consulta cambia.

Claramente, aquí hay un nexo de dolor. Este problema, el número 14606 y la limitación de no poder vincular un parámetro de consulta a una propiedad calculada se combinan para crear una pequeña trampa ingeniosa y frustrante.

Aquí está mi solución: creé una ruta de "selección" anidada que simplemente toma el parámetro de consulta (o, como en el código siguiente, un segmento dinámico), lo desinfecta y establece la propiedad en su controlador principal. Si el índice desinfectado está fuera de los límites, pasa a la ruta del índice anidado, que a su vez vuelve a la ruta de selección anidada con el índice predeterminado. Las rutas anidadas no tienen plantillas ni controladores y la ruta principal no tiene salida; existen únicamente para manejar este problema de enrutamiento.

// 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 gracias por la actualización,

@locks si lo desea, vuelva a abrir un problema de documentación para anotar esto en el setupController (consulte las notas en los menús desplegables de

@mwpastore Parece que podríamos continuar con una publicación en el foro en https://discuss.emberjs.com/ con su solución

Espere a que este problema se cierre con una solución alternativa para solucionar el error que informa, ¿y esa solución implica establecer una propiedad en un captador calculado?

Tengo curiosidad por saber si hay actualizaciones sobre esto.

Estoy usando Ember.run.next dentro de la ruta setupController

¿Fue útil esta página
0 / 5 - 0 calificaciones