Подтвердить что ты не робот

Почему считается, что неправильная практика вызывает триггер: true в функции навигации backbone.js?

Я читал в нескольких местах, что вызов функции Backbone.history.navigate считается плохой практикой.

Например, Addy Osmani sais в своей книге "Разработка приложений Backbone.js"

Также возможно, чтобы Router.navigate() запускал маршрут вдоль с обновлением фрагмента URL-адреса, передав параметр trigger: true. Примечание. Это использование не рекомендуется...

http://addyosmani.github.io/backbone-fundamentals/#backbone.history

Или Derick Bailey в своем блоге даже sais:

В большинстве случаев вы не должны выполнять обработчик маршрутов из своего приложения.

Но я действительно не понимаю причины этого и что было бы лучшим решением.

По-моему, не очень плохо вызвать функцию навигации с помощью триггера: true. Функция маршрута могла при вызове всегда проверять, уже считанные данные уже загружены и показать эти загруженные данные, а не выполнять всю работу снова и снова...

4b9b3361

Ответ 1

Кажется, есть некоторая путаница в отношении того, что Router#navigate делает именно так, я думаю.

Без каких-либо параметров он обновит URL-адрес до предоставленного фрагмента. Например. router.navigate('todo/4/edit') будет обновить URL до #todo/4 И будет создать запись истории браузера для этого URL-адреса. Обработчики маршрутов не запускаются.

Однако установка trigger:true будет обновлять URL-адрес, но он будет также запускать обработчик, который был указан для этого маршрута (в примере Addy он вызывает функцию routers editTodo) и создает запись в истории браузера.

При передаче replace:true url будет обновлен, обработчик не будет вызван, но НЕ создаст запись истории браузера.

Затем, я думаю, что ответ:

причина, по которой обескураживается использование trigger:true, проста, переход из состояния приложения в состояние приложения в состояние приложения требует большого количества времени, в течение которого выполняется другой код, чем при непосредственном переходе в конкретное состояние приложения.

Скажем, у вас есть состояния A, B и C в вашем приложении. Но состояние B строится на состоянии A, а состояние C строится на B. В этом случае, когда вы переходите от B к C, нужно выполнить только определенную часть кода, а при ударе состояния C непосредственно, вероятно, будет выполняться определенная проверка состояния и подготовка:

  • загружены ли эти данные? Если нет, загрузите его.
  • Пользователь вошел в систему? Если не перенаправлять.

и др.

Возьмем пример: State A (#list) показывает список песен. Состояние B (#login) относится к аутентификации пользователя, а состояние C (#list/edit) позволяет редактировать список песен.

Итак, когда пользователь приземляется на состояние A, список песен загружается и сохраняется в коллекции. Он нажимает кнопку входа в систему и перенаправляется на форму входа. Он успешно аутентифицируется и перенаправляется обратно в список композиций, но на этот раз с кнопками удаления рядом с песнями.

Он добавляет последнее состояние (#list/edit).

Теперь, что должно произойти, когда пользователь нажимает на закладку несколько дней спустя? Приложение должно загружать песни, нужно проверить, что пользователь (по-прежнему) вошел в систему и отреагировал соответственно, что в потоке перехода состояния уже было сделано в других состояниях.

Теперь для моей заметки:

Я бы никогда не рекомендовал вышеупомянутый подход в реальном приложении, как в примере. Вы должны проверить, загружена ли коллекция при переходе с B на C, и не просто предположить, что она уже есть. Аналогично, вы должны проверить, действительно ли пользователь зарегистрирован. Это просто пример.

IMO маршрутизатор действительно представляет собой особый вид зрения (подумайте об этом, он отображает состояние приложения и переводит пользовательский ввод в состояние/события приложения) и всегда должен рассматриваться как таковой. Вы никогда не должны полагаться на маршрутизатор на переход между состояниями, но пусть маршрутизатор отражает переходы состояния.

Ответ 2

Я должен не согласиться с ответом @Stephen здесь. И главная причина в том, что использование router.navigate({trigger : true}) дает маршрутизатору ответственность за обработку состояния приложения. Он должен только отражать состояние приложения, а не управлять им.

Кроме того, ответственность за изменение хэша окна - это не View, это работа с маршрутизатором только! Не убирайся от него! Хорошая модульность и разделение проблем делают возможным масштабируемое и поддерживаемое приложение.

Перенаправление человека в новый раздел в вашем приложении

Магистраль - это платформа, управляемая событиями, использует события для общения. Абсолютно не нужно вызывать router.navigate({ trigger : true }), поскольку функциональность не должна быть в маршрутизаторе. Вот пример того, как я использую маршрутизатор, и я думаю, что это способствует хорошей модульности и разделению проблем.

var Router = Backbone.Router.extend({
  initialize: function(app) {
    this.app = app;
  },
  routes: {
    'videoLibrary' : function() { this.app.videoLibrary(); }
  }
});

var Application = _.extend({}, Backbone.Events, {
  initialize: function() {
    this.router = new Router( this );
    this.listenTo( Backbone, 'video:uploaded', function() { 
      this.router.navigate('/videoLibrary');
      this.videoLibrary();
    });
  },
  videoLibrary: function() {
    //do useful stuff
  }
});

var uploadView = Backbone.View.extend({
  //...
  uploadVideo: function() {
    $.ajax({
      //...
      success: function() { Backbone.trigger('video:uploaded'); }
    });
  }
});

В вашем представлении не требуется, нужно знать, что делать, когда пользователь загружается, это чужая ответственность. В этом примере маршрутизатор - это просто точка входа для функциональности приложения, событие, генерируемое uploadView, является другим. Маршрутизатор всегда отражает состояние приложения через хэш-изменения и историю, но не выполняет никаких функций.

Тестируемость

Отделяя проблемы, вы повышаете тестируемость своего приложения. Легко иметь шпиона на Backbone.trigger и следить за тем, чтобы представление работало правильно. Это менее легко издеваться над маршрутизатором.

Управление модулями

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

Ответ 3

По-моему, это считается плохой практикой, потому что вы должны представить себе приложение Backbone, не похожее на приложение Ruby On Rails, а скорее на настольное приложение.

Когда я говорю RoR, я просто говорю фреймворк, поддерживающий маршрутизацию, в том смысле, что маршрут приводит вас к определенному вызову контроллеру для запуска определенного действия (представьте операцию CRUD).

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

Когда вы говорите:

По-моему, называть навигационную функцию нехорошо, триггер: истинный вариант. Функция маршрута могла при вызове всегда проверьте, уже считанные данные уже загружены и показывают, что это загружено данные вместо того, чтобы выполнять всю работу снова и снова...

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

Тем не менее, trigger:true есть ли у нас причина использовать его? По-моему, это можно использовать, если вы полностью меняете представление.

Скажем, у меня есть приложение с двумя вкладками, одно позволяет мне создать один ресурс, а другой - просмотреть список созданных ресурсов. Во вторых вкладках вы фактически загружаете коллекцию, поэтому данные между ними различны. В этом случае я бы использовал trigger:true.

Это говорит о том, что я использую Backbone в течение 2 недель, поэтому я довольно новичок в этом мире, но мне кажется разумным отказать в использовании этой опции.

Ответ 4

Это зависит от вашего контекста.

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

Подумайте об этом. Если вы удаляете запись клиента, не хотите обновлять список клиентов, чтобы отразить это удаление?