Как маршрутизатор может взаимодействовать с представлением, кроме использования глобальной переменной?

Я не могу понять, почему в моем приложении Backbone (приложение Todo) после перезагрузки страницы (CTRL + F5) метод filterTodos не вызывается. Когда я просто нажимаю на ссылки для фильтрации Todos («Активный», «Завершенный») - он вызывается.

Вы можете увидеть эту функцию по ссылкам ниже. Независимо от того, сколько раз вы нажимаете Обновить в браузере - отображаются правильные отфильтрованные результаты:

http://todomvc.com/architecture-examples/backbone/#/completed

http://todomvc.com/architecture-examples/backbone/#/active

У меня есть теория, что это потому, что я слишком рано инициирую filter событие из Router - TodosView еще не инициализирован и, следовательно, он еще не выполняет событие listenTo filter.

Но как Router может сообщить View о необходимости повторного рендеринга (на основе фильтра), если этот View еще не существует? Разве этого нельзя добиться, запустив какое-то событие в Router, как это делаю я? Один из возможных вариантов - иметь глобальную переменную app.FilterState.

Существуют ли другие способы связи между маршрутизатором и еще не созданным View?

Для app.FilterState я установлю его состояние в Router, а затем проверю его в просмотре и вызову функцию filterTodos вручную, вот так, и она будет работать:

views / todos.js

render: function() {
    app.Todos.each(function(todo) {
      this.renderTodo(todo);
    }, this);
    if (app.FilterState !== 'all') { // <--- ADDED CODE
      this.filterTodos(app.FilterState);
    }
    return this;
  }

Существующий исходный код:

routers / router.js

var app = app || {};

var Router = Backbone.Router.extend({
  routes: {
    'all': 'all',
    'active': 'active',
    'completed': 'completed'
  },
  all: function() {
    console.log('all');
    app.Todos.trigger('filter', 'all');
  },
  active: function() {
    console.log('active');
    app.Todos.trigger('filter', 'active');
  },
  completed: function() {
    console.log('completed');
    app.Todos.trigger('filter', 'completed');
  }
});

app.Router = new Router();
Backbone.history.start();

views / todos.js

var app = app || {};

app.TodosView = Backbone.View.extend({
  el: '#todo-list',

  initialize: function(todos) {
    console.log('initialize begin');
    app.Todos.reset(todos);
    this.listenTo(app.Todos, 'add', this.addOneTodo);
    this.listenTo(app.Todos, 'filter', this.filterTodos);
    this.render();
    console.log('initialize end');
  },
  render: function() {
    app.Todos.each(function(todo) {
      this.renderTodo(todo);
    }, this);
    return this;
  },
  renderTodo: function(todo) {
    var todoView = new app.TodoView({model: todo});
    this.$el.append(todoView.render().el);
  },
  addOneTodo: function(todo) {
    this.renderTodo(todo);
  },
  filterTodos: function(filterType) {
    console.log('filter'); // <--- CODE DOES NOT REACH THIS LINE WHEN CALLED ON BROWSER'S REFRESH (F5)
    var active = app.Todos.active();
    var completed = app.Todos.completed();

    if (filterType === 'active') {
      // hide remaining
      _.each(completed, function(todo) {
        todo.trigger('hide');
      });
      //show active
      _.each(active, function(todo) {
        todo.trigger('show');
      });
    }
    else if (filterType === 'completed') {
      _.each(completed, function(todo) {
        todo.trigger('show');
      });
      //show active
      _.each(active, function(todo) {
        todo.trigger('hide');
      });
    }
    else if (filterType === 'all') {
      app.Todos.each(function(todo) {
        todo.trigger('show');
      });
    }
  }
});

person yaru    schedule 07.10.2014    source источник


Ответы (1)


Вы рассматривали возможность использования Backbone Marionette? Он поставляется со встроенной системой связи в пабе, которая делает это очень легко. В целом это дает вам отличную организацию / модульность вашего кода за счет использования подсистемы pub.

person Tom Hammond    schedule 12.10.2014
comment
Кроме того, это стоит немного денег, но это САМОЕ ЛУЧШЕЕ учебное пособие по Backbone / Marionette и содержит довольно много готового к производству кода, если вы будете следовать ему полностью - backbonerails.com - person Tom Hammond; 13.10.2014