2012-07-02 3 views
0

컬렉션에 정의 된 비교 함수를 사용하는 Backbone.js 프로젝트가 있습니다. 페이지를 새로 고칠 때 항목을 정렬하지만 페이지 새로 고침 대신 단추를 클릭하면 정렬되도록하려고합니다.Backbone.js의 이벤트에서 트리거 정렬 방법

var Thing = Backbone.Model.extend({ 
    defaults: { 
     title: 'blank', 
     rank: '' 
    } 
}); 
var ThingView = Backbone.View.extend({ 
    className: 'thingClass', 
    template: _.template('<b><button id="remove">X</button> <b><button id="edit">Edit</button> <%= title %> Rank:<%= rank %></b>'), 
    editTemplate: _.template('<input class="name" value="<%= name %>" /><button id="save">Save</button>'), 

    events: { 
     "click #remove": "deleteItem", 
     "click #edit": "editItem", 
     "click #save": "saveItem", 
    }, 
    deleteItem: function() { 
     console.log('deleted'); 
     this.model.destroy(); 
     this.remove(); 
    }, 
    editItem: function() { 
     console.log('editing'); 
     this.$el.html(this.editTemplate(this.model.toJSON())); 
    }, 
    saveItem: function() { 
     console.log('saved'); 
     editTitle = $('input.name').val(); 
     console.log(editTitle); 
     this.model.save({ 
      title: editTitle 
     }); 
     this.$el.html(this.template(this.model.toJSON())); 
    }, 
    render: function() { 
     var attributes = this.model.toJSON(); 
     //console.log (attributes); 
     this.$el.append(this.template(attributes)); 
     return this; 
    } 
}); 
var ThingsList = Backbone.Collection.extend({ 
    model: Thing, 
    localStorage: new Store("store-name"), 
    comparator: function(thing) { 
    return thing.get('rank'); 
    }, 
}); 

var thingsList = new ThingsList; 
var ThingsListView = Backbone.View.extend({ 
    el: $('body'), 
    events: { 
     'click #add': 'insertItem', 
     'click #sort': 'sortItems', 
    }, 
    initialize: function() { 
    thingsList.fetch(); 
    thingsList.toJSON(); 
     this.render(); 
     this.collection.on("add", this.renderThing, this); 
     this.collection.on("reset", this.clearRender, this); 
    }, 
    insertItem: function (e) { 
     newTitle = $('#new-item').val(); 
     newRank = $('#rank').val(); 
     newThing = new Thing({ 
      title: newTitle, 
      rank: newRank 
     }); 
     this.collection.add(newThing); 
     newThing.save(); 
     console.log(this.collection.length); 
    }, 

    sortItems: function (e) { 
     console.log('clicked sort button'); 
     this.collection.sort(); 
     this.$el.detach('.item'); 
    }, 

    render: function() { 
     _.each(this.collection.models, function (items) { 
      this.renderThing(items); 
     }, this); 

    }, 
    renderThing: function (items) { 
     var thingView = new ThingView({ 
      model: items 
     }); 
     this.$el.append(thingView.render().el); 
    }, 

    clearRender: function() { 
     console.log('clear render called') 

     _.each(this.collection.models, function (items) { 
      //this.remove(); 
      this.$el.remove(".thingClass") 
      this.renderThing(items); 
     }, this); 

    }, 



    test: function (items) { 
     console.log('test worked'); 
    }, 


}); 
var thingsListView = new ThingsListView({ 
    collection: thingsList 
}); 
+0

'Sort()'는 reset 이벤트를 호출합니다. 해당 이벤트에 뷰를 구독하고 콜렉션을 다시 렌더링하십시오. – Deeptechtons

답변

0

가 확실 컬렉션 자체를 의지하지 않는 있습니까 : 여기 내 코드? 컬렉션의 모델 순서에 따라 이미 렌더링 된 페이지의 순서가 변경되지는 않습니다.

당신이하려는 것은 이미 렌더링 된 항목을 사용하는 것이므로 컬렉션을 다시 렌더링해야한다고 생각합니다. 그렇게 할 계획이라면 뷰를 캐시하고 정렬에서 관련 요소를 DOM에서 분리하고 올바른 순서로 다시 첨부하는 것이 좋습니다. 예를 들어

var ThingsListView = Backbone.View.extend({ 
    _views: {}, 

    initialize: function() { 
     this.collection.bind('add', this.add, this); 
     this.collection.bind('reset', this.render, this); //sort triggers a reset 
    }, 

    add: function (thing) { 
    var view = new ThingView({model: thing}); 
    this._views[thing.cid] = view; //use client id of model as key for the views cache 
    this.$el.append(view.render().el); 
    }, 

    render: function() { 

    $('li, this.$el).detach(); //detach so that bound events aren't lost 
    _.each(this.collection.models, function(thing) {   
     this.$el.append(this.views[thing.cid].el); //get view from cache 
    },this); 

    }, 

    sort: function() { 
    this.collection.sort(); 
    } 

} 

}) 

(I 컬렉션 뷰는 '엘이'용기 'UL', 나 또한 돈을 참조 가지고 여기에 있으리라 믿고있어 내 예제 코드와 당신의 차이의 커플

편집 : 내가 게시 한 예제 코드에서 그렇게 명확하지 않을 수도 있으므로 @Deptechtons가 당신이 정렬 할 때 말한 것과 같이 시작해야한다고 언급 했어야합니다. (예 : thingListView.sort(); 그 컬렉션은 triggers a reset 이벤트

Edit2가 : 현재 뷰를 제거하려면 뷰, 다음 가장 쉬운 방법은 캐싱에 관심이 없다가 probablly 당신의 clearRender 방법에

var ThingView = Backbone.View.extend({ 
    className: 'thingClass', 
    //rest of your thingViewCode 

그런 다음 렌더링 DIV에 클래스를 추가하는 것입니다 경우 단지에 $(".thingClass", this.$el).remove(); 추가 메소드의 시작.

+0

내 모델이 리가 아닌 div에 있습니다. 내가 sortItems를 추가하면 발견했습니다 : function (e) { this.render(); }, 다음 목록은 기존 목록 아래 올바른 순서로 렌더링됩니다. 그래서 만약 내가 스크린에서 첫 번째 정렬되지 않은 버전을 제거하는 방법을 알아낼 수 있다면, 나는 그것이 효과가있을 것이라고 생각한다. – user1469779

+0

실제로 사용하고있는 것의 차이를 만들지는 않습니다. 예제로 사용했습니다. 컨테이너 div에 클래스를 추가하고이를 사용하여 원하는 경우 분리 할 수 ​​있습니다 ('this. $ el.detach ('. youClass ');). – Jack

+0

나는 이전의 답변을 이해하기 어렵고 지나치게 복잡하게 만들고자 노력하고 있지만 도움을 주셔서 감사합니다. 나는 지금 어디에 있는지 보여주는 질문을 업데이트했다. 콜렉션 뷰의 sortItems 함수는 컬렉션을 정렬하고 클래스 주변 모델을 분리합니다. 그것은 정렬하지만 추가하지 않은 원래보기에서 정렬, 내가 원하는 것을 제거하지 않습니다. – user1469779

관련 문제