2011-07-28 36 views
39

我已經獲得了一大堆啓動時加載的任務。
我想根據選定的列表/收件箱顯示它們,以便每個列表不會有額外的負載。Backbone.js - 在視圖中過濾和顯示收集數據的正確方法

window.Task = Backbone.Model.extend({}); 

window.TasksCollection = Backbone.Collection.extend({ 
    model: Task, 
    url: '/api/tasks', 
    inbox: function() { 
     return this.filter(function(task) { 
      return task.get('list') == null; 
     }); 
    }, 
    list: function(id) { 
     return this.filter(function(task) { 
      return task.get('list') == id; 
     }); 
    } 
}); 

window.tasks = new TasksCollection; 

window.TaskView = Backbone.View.extend({ 
    tagName: 'li', 
    template: _.template($('#item-template').html()), 
    initialize: function() { 
     _.bindAll(this, 'render', 'close'); 
     this.model.bind('change', this.render); 
     this.model.view = this; 
    }, 
    render: function() { 
     $(this.el).html(this.template(this.model.toJSON())); 
     this.setContent(); 
     return this; 
    }, 
}); 

window.TasksView = Backbone.View.extend({ 
    el: '#todo-list', 
    collection: tasks, 
    initialize: function() { 
     _.bindAll(this, 'render'); 
     this.collection.bind('reset', this.render); 
     this.collection.fetch(); 
    }, 
    render: function() { 
     var t = this; 
     $(t.el).html(''); 
     this.collection.each(function(task) { 
      var view = new TaskView({ model:task }); 
      $(t.el).append(view.render().el); 
     }); 
     return this; 
    }, 
}); 

window.Nicetask = Backbone.Router.extend({ 
    routes: { 
     '':    'inbox', 
     '/inbox':  'inbox', 
     '/list/:id': 'list', 
    }, 
    initialize: function() { 
     _.bindAll(this, 'inbox', 'list'); 
     window.tasksView = new TasksView; 
    }, 
    inbox: function() { 
     tasks.reset(tasks.inbox()); 
    }, 
    list: function(id) { 
     tasks.reset(tasks.list(id)); 
    } 
}); 

此代碼的工作,但reset()函數從任務收集實際列表中刪除其它任務。而在另一條路線上,任務收集是空的。

是否有任何合理的方法來實現這一目標?謝謝你的任何想法。

PS:新手骨幹


UPDATE

THX到@sled和@ibjhb徵求意見,這裏是工作液的片段。

window.TasksView = Backbone.View.extend({ 
    el: '#todo-list', 
    collection: Backbone.Collection.extend(), 
    initialize: function() { 
     _.bindAll(this, 'render', 'addOne', 'addAll'); 
     this.collection.bind('add', this.addOne); 
     this.collection.bind('reset', this.render); 
    }, 
    render: function(data) { 
     $(this.el).html(''); 
     _.each(data, function(task) { 
      this.addOne(task); 
     }, this); 
     return this; 
    }, 
    addOne: function(task) { 
     var view = new TaskView({ model:task }); 
     $(this.el).append(view.render().el); 
    }, 
}); 

window.Nicetask = Backbone.Router.extend({ 
    routes: { 
     '':    'inbox', 
     '/inbox':  'inbox', 
     '/today':  'today', 
     '/list/:id': 'list', 
    }, 
    initialize: function() { 
     _.bindAll(this, 'inbox', 'today'); 
     window.tasksView = new TasksView; 
     window.menuView = new MenuListView; 
     tasks.fetch(); 
    }, 
    inbox: function() { 
     tasksView.render(tasks.inbox()); 
    }, 
    today: function() { 
     tasksView.render(tasks.today()); 
    }, 
    list: function(id) { 
     tasksView.render(tasks.list(id)); 
    } 
}); 
+2

拉出我的頭髮一個小時。感謝你的回答! – Chev

+1

使用Backbone Marionette可能嗎?這解決了很多問題。 – Blacksonic

+0

嗨Juraj,我有一個情況,我得到一個JSON樹,我必須創建集合,只有當我們點擊子節點。例如。 Root1> child1> subchild1。在這裏,我必須首先顯示根節點,並且只有在單擊根節點'Root1'時應該顯示子列表'child1'或者應該創建子集合。我剛剛發現你的情況有點類似。你能對此有所瞭解嗎?在此先感謝 –

回答

4

我想你需要使用另一個集合。例如,在您的收件箱中,執行此操作:

inbox: function(){ 
    currentCollection = new TasksCollection(tasks.inbox()); 
} 

我還沒有測試過這個,但是當您執行.reset();要刪除所有模型和加載在通過的人。

1

一個快速修正你的解決方案,您使用的

$(this.el).html(''); 

我的理解是你的意見和相關事件綁定仍然會在瀏覽器中存在內存,因此理想情況下需要在TaskView上使用view.remove()來正確清除事件綁定以及html。


這是一個稍微不同的看法上,我一直在尋找一個解決類似的問題的答案,希望這可能是幫助他人。

我的問題: - 過濾模型屬性的完整集合。例如。用戶單擊模型視圖,獲取(某些)屬性列表,選擇屬性過濾集合以僅顯示具有相同值的屬性。

我走的路線是通過調用視圖中的採集方法,在我的情況的看法是特定的模型,因此:

this.model.collection.myFilter(attr,val); 

其中attr是與相關的模型的屬性收集,然後在過濾器類似

myFilter: function(attr, val){ 
    var groupByAttr = this.groupBy(function(article){ 
     var res = (val === undefined)? true : (article.get(attr) == val); 
     article.set({selected:res}); 
     return res; 
    }); 
    return groupByAttr; 
} 

我已經使用._groupBy因爲這將返回2門陣列(正/負),其可以使用的。通過設置模式屬性「選中」,並綁定到模型視圖中,我可以很容易地切換顯示或隱藏視圖的類。

if(val === undefined)被添加爲通過調用沒有值的相同方法來清除過濾器的簡單方法。

+0

有趣。你如何'JSONify'模板的結果? – charlysisto

4

@sled在您發佈的代碼中存在拼寫錯誤,請參閱評論內嵌。你是否把這個作爲項目發佈在某個地方?

// add models 
add: function(models, options) { 
    // TYPO: next line was missing, so single models not handled. 
    models = _.isArray(models) ? models.slice() : [models]; 

    var self = this; 

    models = _.filter(models, this.filter); 

    // return if no models exist 
    // TYPO: returned undefined, so was not chainable 
    if(models.length == 0) { return this; } 

    // actually add the models to the superset 
    this.superset.add(models, options); 
    return this; 
}, 

// remove models 
remove: function(models, options) { 
    // TYPO: next line was missing, so single models not handled. 
    models = _.isArray(models) ? models.slice() : [models]; 

    // remove model from superset 
    this.superset.remove(_.filter(_.filter(models, function(cm) { 
    // TYPO: not 'm != null', causes error to be thrown 
    return cm != null; 
    }), this.filter), options); 
    // TYPO: missing return so not chainable 
    return this; 
}, 
相關問題