setupController не вызывается при использовании {{linkTo}} или transtionTo(path, model);

Есть ли причина, по которой setupController не будет вызываться при использовании {{linkTo}}? У меня есть два экземпляра в моем приложении, где используется linkTo, и во втором случае. Это не работает. Единственная разница, которую я вижу, заключается в том, что в первом случае linkTo используется в цикле, а во втором — нет. Ниже приведен соответствующий код для нерабочего:

App.Router.map(function() {
    this.resource("search", { path: "/search/:args" });
});

App.SearchCriteria = Ember.Object.extend({ });

App.SearchRoute = Ember.Route.extend({
    serialize: function(model, params) {
        // .. some code that converts model to a string called args
        return {'args': args}

    },
    model: function(params) {
        // convert args, which is query string-formatted, to an object
        // and then make a App.SearchCriteria object out of it.
        return App.SearchCriteria.create($.deparam(params.args));
    },
    setupController: function(controller, model) {
        controller.set("searchCriteria", model);
    }
});

В шаблоне поиска:

{{view Ember.Checkbox checkedBinding="searchCriteria.music"}} Music
{{#linkTo search searchCriteria}}Search{{/linkTo}}

Последнее, что я вижу в логах:

Transitioned into 'search' 

Обычно я вижу, как в какой-то момент вызывается setupController, но этого не происходит по какой-то причине. Я даже пытался использовать метод {{action}} для вызова обработчика, а затем использовать transtionTo, но результат был тот же.

ОБНОВЛЕНИЕ 1: Добавление дополнительной информации

Единственная разница между рабочим и нерабочим случаями заключается в том, что в рабочем случае {{linkTo}} вызывается из того же шаблона, что и у контроллера и маршрутизатора (т. е. linkTo находится в шаблоне поиска, и его вызов SearchRoute). В рабочем случае linkTo вызывается для SearchRoute, но из другого шаблона, принадлежащего другому маршрутизатору).

После некоторой отладки кода Ember в Chrome я обнаружил, что маршрутизатор не вызывается, потому что partitioned.entered пуст. В рабочем случае оно не пусто.

  var aborted = false;
  eachHandler(partition.entered, function(handler, context) {
    if (aborted) { return; }
    if (handler.enter) { handler.enter(); }
    setContext(handler, context);
    if (handler.setup) {
      if (false === handler.setup(context)) {
        aborted = true;
      }
    }
  });

ОБНОВЛЕНИЕ 2. Обнаружена основная проблема — ошибка?

Я думаю, что понимаю основную причину того, почему обработчик не запускается, и я думаю, что это потому, что метод partitionHandlers(oldHandlers, newHandlers) не считает, что модель изменилась, поэтому не запускает обработчик.

Чтобы быть конкретным, это соответствующая часть представления:

{{view Ember.Checkbox checkedBinding="searchCriteria.music"}} Music
{{#linkTo search searchCriteria}}Search{{/linkTo}}

Хотя пользователь снимает флажок (тем самым изменяя состояние searchCriteria), Эмбер не думает, что searchCriteria чем-то отличается, поэтому ничего не делает.

Это ошибка?


person Nightwolf    schedule 31.03.2013    source источник
comment
Это сбивает с толку, но основная причина в том, что объект searchCriteria является одним и тем же объектом, хотя и с другим содержимым. Поскольку Ember использует равенство объектов, он не видит в этом изменения. Вы можете исправить это, создав новый объект searchCriteria при изменении параметра.   -  person Luke Melia    schedule 03.09.2013
comment
Это не решение основной проблемы, но это обходной путь для тех, кому это может понадобиться. В соответствии с тем, что упомянул автор этого вопроса, хуки model и setupController не запускаются при использовании link-to или transitionTo для перехода к родительскому маршруту. На данный момент мне пришлось создать отдельный маршрут для ребенка, и он работает.   -  person Raymond Kalonji    schedule 31.07.2015


Ответы (1)


Я не уверен, в чем ваша проблема, но это может помочь.

setupController вызывается каждый раз при вводе маршрута. Но хук model может вызываться не каждый раз.

См. руководство по Ember: http://emberjs.com/guides/routing/specifying-a-routes-model/

Примечание. Для маршрута с динамическим сегментом будет вызываться хук модели только при вводе его через URL-адрес. Если маршрут вводится через переход (например, при использовании помощника link-to Handlebars), то контекст модели уже предоставлен, и хук не выполняется. Маршруты без динамических сегментов всегда будут выполнять хук модели.

Вообще говоря, если вы нажмете ссылку, сгенерированную link-to, чтобы ввести маршрут, Ember не вызовет хук model для этого маршрута. Вместо этого он передает модель (параметр link-to) этому маршруту.

Философия здесь заключается в том, что поскольку у клиента уже есть контекст модели, Ember считает, что нет необходимости снова получать его с сервера (это работа model хука).

person darkbaby123    schedule 19.10.2013
comment
+1 за объяснение всегда вызывается setupController. Не решил мою проблему, но направил меня в правильном направлении. - person Cameron; 03.07.2017