2012-05-17 2 views
0

reset 속성을 사용하여 선택 상자를 사용하여 단일보기에서 필터링 된 콜렉션을 렌더링하려고합니다. 첫 번째 문제는 선택 상자와 렌더링 된 내용이 모두 작동하도록 동일한 div에 나타나야한다는 것입니다. 이게 정상인가? 두 번째 문제는 필터링 된 결과 만 표시하는 대신 필터링 된 컬렉션을 렌더링 된 내용의 끝 부분에 추가하는 대신 교체합니다. 내 ._each 함수에 추가되는 것을 알고 있습니다. 필터링 된 항목을 추가하기 때문에 작동하지 않습니다. 전체 컬렉션의 끝.Backbone.js가 단일보기로 재설정 된 콜렉션을 렌더링합니다.

(function($) { 

    var images = [ 
     { tags: "Fun", date : "April 3, 2012", location : 'Home', caption : 'Having fun with my lady'}, 
     { tags: "Chillin", date : "April 4, 2012", location : 'Home', caption : 'At the park with my lady'}, 
     { tags: "Professional", date : "April 5, 2012", location : 'Home', caption : 'At the crib with my lady'}, 
     { tags: "Education", date : "April 6, 2012", location : 'Home', caption : 'Having fun with my baby'}, 
     { tags: "Home", date : "April 3, 2012", location : 'Home', caption : 'Having fun with my lady'}, 
     { tags: "Professional", date : "April 4, 2012", location : 'Home', caption : 'At the park with my lady'}, 
     { tags: "Fun", date : "April 5, 2012", location : 'Home', caption : 'At the crib with my lady'}, 
     { tags: "Chillin", date : "April 6, 2012", location : 'Home', caption : 'Having fun with my baby'}, 
     { tags: "Fun", date : "April 3, 2012", location : 'Home', caption : 'Having fun with my lady'}, 
     { tags: "Education", date : "April 4, 2012", location : 'Home', caption : 'At the park with my lady'}, 
     { tags: "Personal", date : "April 5, 2012", location : 'Home', caption : 'At the crib with my lady'}, 
     { tags: "Personal", date : "April 6, 2012", location : 'Home', caption : 'Having a play date'} 
    ]; 


var Item = Backbone.Model.extend({ 
    defaults : { 
     photo : 'http://placehold.it/200x250' 
    } 
}); 

var Album = Backbone.Collection.extend({ 
    model : Item 
}); 

var ItemView = Backbone.View.extend({ 
el : $('.content'), 

    initialize : function() { 
     this.collection = new Album(images); 
     this.render(); 
     $('#filter').append(this.createSelect()); 
     this.on("change:filterType", this.filterByType); 
     this.collection.on('reset', this.render, this); 
    }, 
    template : $('#img_container').text(), 
    render : function() { 
     var tmpl = _.template(this.template); 
     _.each(this.collection.models, function (item) { 
      this.$el.append(tmpl(item.toJSON()));     
     },this); 
}, 

events: { 
    "change #filter select" : "setFilter" 
}, 

getTypes: function() { 
    return _.uniq(this.collection.pluck("tags"), false, function (tags) { 
     return tags.toLowerCase(); 
     }); 
}, 

createSelect: function() { 
    var filter = this.$el.find("#filter"), 
     select = $("<select/>", { 
      html: "<option>All</option>" 
     }); 

    _.each(this.getTypes(), function (item) { 
     var option = $("<option/>", { 
      value: item.toLowerCase(), 
      text: item.toLowerCase() 
     }).appendTo(select); 
    }); 
    return select; 
}, 

setFilter: function (e) { 
    this.filterType = e.currentTarget.value; 
    this.trigger("change:filterType"); 
}, 

filterByType: function() { 
    if (this.filterType === "all") { 
     this.collection.reset(images); 
    } else { 
     this.collection.reset(images, { silent: true }); 
     var filterType = this.filterType, 
      filtered = _.filter(this.collection.models, function (item) { 
      return item.get("tags").toLowerCase() === filterType; 
     }); 
     this.collection.reset(filtered); 
    } 
} 

}); 

var i = new ItemView(); 


})(jQuery); 

답변

3

는 확실히 말을 조금 어렵다 마크 업을 보지 않고,하지만 난 당신이 백본에 이벤트를 바인딩 할 때 사용 때문에 선택의 필요가 같은 사업부에 될 수있는 이유는 의심 : 여기 아래에있는 내 코드 샘플입니다 사용하는 이벤트 해시는 el을 이벤트 위임의 루트 요소로 사용합니다.

컬렉션이 대체되는 대신 추가되는 이유는 어디에도 현재 내용을 비우지 않는다는 것입니다. 렌더 메서드 시작 부분에 this.$el('.itemCnt').empty() 행을 가져야합니다.

별도의 요점으로, 각 항목에 대한보기 및 캐쉬 할 개체가 있다고 생각할 수 있습니다. 컬렉션을 재설정하는 대신 필터가 변경 될 때마다 모든 항목을 분리하고 다시 생성하지 않고 필터링 된 요소를 다시 연결할 수 있습니다 그들의 마크 업. 예를 들어

, 속임수를 썼는지

var ItemView = Backbone.View.extend({ 
    el : $('.content'), 
    _views: {}, 
    //... 

    add: function(item) { 
    var view = new ItemView({model: item}); 
    this._views[item.cid] = view; 
    } 

    render: function (filteredItems) { 
     this.$el.find('.ItemCnt .item').detach(); 

    var frag = document.createDocumentFragment(); 

     _.each(filteredItems, function(item) { 
     frag.appendChild(this._views[item.cid].el); 
    } 
     this.$el.find('.ItemCnt').append(frag); 
    } 
+0

의 라인을 따라 뭔가! 쓰레기 한 무리! 나는 또한 당신이 제안한 것을 시도 할 것입니다. 그래서 내가 본 마스터보기를 사용하는 데 더 많은 시간이 걸린다. 다시 Thx! – Teeman

+0

답이 귀하의 질문을 해결할 수 있다면 왼쪽에있는 체크 표시를 선택하여 수락을 고려하는 것이 좋습니다. – Jack

관련 문제