【发布时间】:2014-12-01 18:58:32
【问题描述】:
我不明白为什么在我重新加载页面 (CTRL+F5) 后在我的 Backbone 应用程序(Todo 应用程序)中没有调用 filterTodos 方法。当我简单地单击链接以过滤 Todos(“活动”、“已完成”)时 - 它确实被调用了。
您可以在下面的链接中看到此功能。无论您在浏览器中单击刷新多少次 - 都会显示正确的过滤结果:
http://todomvc.com/architecture-examples/backbone/#/completed
http://todomvc.com/architecture-examples/backbone/#/active
我有一个理论,这是因为我太早从 Router 触发了 filter 事件 - TodosView 尚未初始化,因此它没有listenTo filter 事件然而。
但是如果View 尚不存在,Router 如何通知View 重新渲染自己(基于过滤器)?难道不能像我一样通过在Router 中触发一些事件来实现吗?一种可能的选择是使用全局变量app.FilterState。
Router 和尚未构建的 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;
}
现有源代码:
路由器/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');
});
}
}
});
【问题讨论】:
标签: backbone.js backbone-views backbone-events backbone-routing