0

我不明白,爲什麼在我的骨幹應用(待辦事項應用程序)我重新加載頁面(CTRL + F5)一個filterTodos方法不會被調用後。當我只點擊鏈接來過濾Todos(「主動」,「完成」) - 它確實被調用。路由器如何與除全局變量以外的視圖交談?

你可以看到在下面的鏈接此功能。不管你有多少次點擊瀏覽器刷新 - 顯示正確的篩選結果:

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

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

我有一個理論,那是因爲我從Router太早觸發filter事件 - 一個TodosView尚未初始化,因此它不會listenTofilter事件。

但如何Router可以通知View重新呈現自己(基於過濾器),如果這View不存在呢?難道不能像我一樣通過觸發Router中的某個事件來實現嗎?一種可能的選擇是擁有一個全局變量app.FilterState

是否有通信的路由器和非構造尚未查看之間的任何其他的方法呢?

對於app.FilterState我將其狀態在Router,然後將其簽入查看和調用filterTodos功能,像這樣手動,它會工作:

的意見/ 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(); 

的意見/ 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'); 
     }); 
    } 
    } 
}); 

回答

1

你有沒有使用骨幹木偶考慮?它內置了一個內置的酒吧子通信系統,這使得它非常容易。總體而言,它通過使用pub子系統爲您提供了一個偉大的組織/模塊化代碼。

+0

此外,它的成本一點錢,但它是最好的骨幹/木偶教程在那裏,並配有相當多的生產就緒代碼,如果你跟着它一路過關斬將 - http://www.backbonerails.com/ – 2014-10-13 13:10:31