Ember.js: установка свойства контроллера в `setupController` не обновляет параметр запроса

Созданный на 21 авг. 2014  ·  29Комментарии  ·  Источник: emberjs/ember.js

если у вас есть контроллер, определенный как

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

и в Routes setupController вы делаете что-то вроде ...

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

Параметр запроса не устанавливается в URL-адресе.

Здесь вы можете увидеть рабочую корзину: http://emberjs.jsbin.com/dekuj/1/edit

Bug Inactive Query Params

Самый полезный комментарий

Я тоже вижу эту проблему в Ember 2.11, попытка очистить параметр запроса в контроллере не имеет никакого эффекта, обходной путь

Все 29 Комментарий

Исправлено с помощью Ember.run.later (чтобы сначала все было полностью материализовано): http://emberjs.jsbin.com/kowoqo/1/edit

@machty - Какое здесь ожидаемое поведение?

Я думал, у нас есть явные тесты для этой ... проверки.

Я думаю, что это ошибка ... у нас есть тесты для этого, но только в контексте transitionTo а не начальной загрузки приложения.

работает: http://jsbin.com/mejeto/1#/about

Я добавил неудачный тест на эту ошибку https://github.com/emberjs/ember.js/pull/5473
Попробую исправить это

Я думаю, что наткнулся на связанную проблему, поэтому не уверен, нужен ли отдельный билет здесь, в 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'
            });
        }
    }
});

Это работает во всех случаях, кроме загрузки, когда выдает 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.

Можно исправить с помощью Ember.run.next

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

хотя это кажется неправильным.

JSBins:
Без Ember.run.next выдает ошибку
С Ember.run.next печатает "повторно" в консоли

@ Igor10k У меня точно такая же проблема, модальная и все такое. Обертывание в Ember.run.next исправляет это, но мне это тоже кажется неправильным.

Может ли кто-нибудь подтвердить, что это все еще проблема в 1.8?

@wagenet да, это все еще проблема в 1.8:
http://emberjs.jsbin.com/lezuhu/1/edit?html , js, вывод

и канарейка:
http://emberjs.jsbin.com/doyohe/1/edit?html , js, вывод

@machty - Мысли?

Я думаю, что это тоже ошибка для меня, использующего 1.8.1. Я хочу вызывать специальный метод на моем контроллере каждый раз, когда изменяется конкретный параметр queryParam. У меня есть маршрутизатор, который выглядит примерно так.
Любой совет?

// ...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 - Идеи, с чего начать копаться в этом?

У меня такая же проблема. this.set () в контроллере не будет обновлять параметр запроса в URL-адресе

App.SearchController = Ember.Controller.extend ({
queryParams: ['домен'],
домен: нуль,

domainField: Ember.computed.oneWay ('домен'),
действия: {
searchSubmit: function () {
this.set ('домен', this.get ('domainField')); // Это устанавливает параметр 'domain', но не изменяет URL-адрес. Таким образом, модель в App.SearchRoute никогда не вызывается должным образом.
}
},
});

App.SearchRoute = Ember.Route.extend ({
queryParams: {
домен: {
refreshModel: true // Включаем полный переход
},

},
model: function (params) {
var domain = params.queryParams.domain;

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

},
действия: {
refresh: function () {
Ember.Logger.log ('Маршрут сейчас обновляется ...');
this.refresh ();
}
},
});

Не могли бы вы предоставить временное решение?

Чтобы уточнить: this.set () в моем коде внесет изменения в объект Class, но не изменит URL-адрес вообще

Это давно, но кажется, что это все еще проблема? Я не могу понять обстоятельства, но периодически, когда я пытаюсь установить параметр запроса из контроллера, он не распространяется на URL-адрес. Я могу проверить значение свойства на контроллере, и оно правильно установлено, но URL-адрес не изменился. Я безуспешно пытался использовать Ember.run.next . Горе!

У вас тоже есть эта проблема

@rwjblue : Есть ли обновления по этому

Есть обновления? Здесь даже при изменении значения из контроллера URL-адрес обновляется на пару мс и возвращается к старому значению, даже если контроллер имеет новое значение в переменной

Вот обходной путь:

В контроллере добавьте наблюдателя, который изменяет параметр запроса в следующем цикле выполнения после того, как он был установлен. В этом примере я хотел удалить параметр запроса token из URL-адреса, и этот подход отлично работает.

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

Просто столкнулся с этим сегодня, когда пытался установить параметр запроса из setupController при загрузке. run.next кажется обходным путем, но я думаю, что правильным решением было бы иметь 2 маршрута, и при загрузке первый маршрут будет выполнять transitionTo второй маршрут со значением параметра запроса.

Эмбер 2.8

Пометить проблему как неактивную в соответствии с нашей политикой сортировки .

Я тоже вижу эту проблему в Ember 2.11, попытка очистить параметр запроса в контроллере не имеет никакого эффекта, обходной путь

РЕДАКТИРОВАТЬ: игнорируйте весь этот джаз. Здесь есть некоторая плохая / неправильная информация, и @locks указала мне на гораздо лучшее решение - с параметром запроса вместо динамического сегмента - get (мои предыдущие попытки включали привязку параметра запроса к вычисляемому свойству, которое дезинфицировалось и устанавливалось на set ) . Простите за шум!


Лучшее решение ...

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


Исходная проблема и решение ...

Я потерял большую часть вчерашнего дня из-за этой проблемы, которая все еще сохраняется в бета-версии 2.14. Мой вариант использования - очистка параметра запроса для использования в качестве индекса в Ember.Array. Если он имеет неправильный формат (например, NaN или строка) и / или выходит за границы, он должен использовать индекс по умолчанию и обновлять URL-адрес, чтобы отразить настройку (чтобы события в ответ на будущие клики запускались соответствующим образом - я могу объяснить это дальше, помогите доказать, что это не просто косметическая проблема).

Я не могу установить свойство из setupController() поскольку оно не обновляет URL-адрес (как описано в этой проблеме). Я не могу установить его в следующем тике с помощью Ember.run, потому что это вступит в силу слишком поздно (т.е. для доступа к массиву уже использовался недействительный индекс). Я не могу установить его один раз, а затем установить его снова в следующем тике, чтобы обновить URL-адрес, потому что нет изменения свойства (или, по крайней мере, я подозреваю, что это причина, по которой он не работает).

Я не могу использовать вычисляемое свойство с установщиком очистки в контроллере, потому что вы не можете привязать параметр запроса к вычисляемому свойству. Я не могу использовать наблюдателя для обычного свойства, потому что вы не можете установить свойство, которое вы наблюдаете. Я не могу использовать обозреватель с Ember.run из-за проблемы, описанной выше.

Я не могу вызвать this.transitionTo({ queryParams: .. }) из setupController() или beforeModel() hook или controller.transitionToRoute({ queryParams: .. }) из setupController() из-за # 14606 и связанных проблем. Я не могу установить refreshModel равным true для параметра запроса, потому что в ловушке model() происходят другие вещи, которые не должны повторяться при изменении этого параметра запроса.

Ясно, что здесь есть некоторая боль. Эта проблема, проблема №14606 и ограничение невозможности привязать параметр запроса к вычисляемому свойству - все это вместе создает аккуратную, неприятную ловушку.

Вот мой обходной путь: я создал вложенный маршрут «select», который просто принимает параметр запроса (или, как в приведенном ниже коде, динамический сегмент), очищает его и устанавливает свойство на его родительском контроллере. Если очищенный индекс выходит за границы, он переходит к маршруту вложенного индекса, который, в свою очередь, переходит обратно к маршруту вложенного выбора с индексом по умолчанию. Вложенные маршруты не имеют шаблонов или контроллеров, а родительский маршрут не имеет выхода; они существуют исключительно для решения этой проблемы маршрутизации.

// 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 спасибо за обновление, мы его закроем. Хороших выходных!

@locks, если хотите, повторно setupController (см. примечания в раскрывающихся списках от

@mwpastore Похоже, мы могли бы дополнить сообщение на форуме https://discuss.emberjs.com/ с вашим решением

Подождите, чтобы эта проблема была закрыта с помощью альтернативного решения для обхода ошибки, о которой он сообщает, и это решение включает установку свойства в вычисляемом геттере?

Мне любопытно, есть ли обновления по этому поводу.

Я использую Ember.run.next внутри setupController Route

Была ли эта страница полезной?
0 / 5 - 0 рейтинги