3

본인 및 백과 사전에 처음입니다. 이제 marioettejs의 compositeview로 페이징을 구현하려고합니다. 아래 코드는 내 사용자 정의 호출기를 통해 새로운 가져 오기가 수행 될 때 기존 데이터가 추가하는 대신 새로운 데이터 집합으로 대체된다는 것을 의미합니다. 이것을 극복하도록 도와주세요! 미리 감사드립니다.Backbone Marionette 복합 뷰를 사용하여 페이징을 수행하려면 어떻게해야합니까?

define(['text!/Templates/projects/_GroupItem.html', 'collections/projects/groups'], function (ProjectGroupsTmpl, GroupCollection) { 
    var GroupItemView = Backbone.Marionette.ItemView.extend({ 
     tagName: 'li', 
     template: _.template(ProjectGroupsTmpl) 
    }); 
    var CompositeView = Backbone.Marionette.CompositeView.extend({ 
     template: _.template("<ul id='ulgroups' ></ul>"), 
     itemView: GroupItemView, 
     itemViewContainer: '#ulgroups', 
     initialize: function (params) { 
      this.isLoading = false; 
      this.ProjectID = params.id; 
      this.collection = new GroupCollection(); 
      this.getData(); 
      var self = this; 
      $(window).scroll(function() { 
       self.checkScroll(); 
      }); 
     }, 
     getData: function() { 
      var that = this; 
      this.isLoading = true; 
      this.collection.fetch({ 
       data: { ProjectID: this.ProjectID }, 
       success: function (collection, response, options) { 
        that.isLoading = false; 
       } 
      }); 
     }, 
     checkScroll: function() { 
      var triggerPoint = 100; // 100px from the bottom 
      if (!this.isLoading && $(window).scrollTop() + $(window).height() + triggerPoint > $(document).height()) { 
       this.collection.page += 1; // Load next page 
       this.getData(); 
      } 
     }, 
     appendHtml: function (collectionView, itemView, index) {    
      $(this.itemViewContainer).append(itemView.el); 
     } 
    }); 
    return CompositeView; 
}); 

답변

2

위의 문제를 해결하기 위해 backbone.paginator을 사용했으며 정상적으로 작동합니다. 아래는 새로운 코드입니다.

컬렉션 :

define([ 
    'jquery', 
    'underscore', 
    'backbone', 
    'helper', 
    'paginator' 
], function ($, _, Backbone) { 
    var Groups = Backbone.PageableCollection.extend({ 
     url: 'projects/_groups', 
     mode: "infinite", 
     state: { 
      pageSize: null 
     }, 
     queryParams: { 
      totalPages: null, 
      totalRecords: null 
     } 
    }); 
    return Groups; 
}); 

마리오네트의 CompositeView :

define(['text!/Templates/projects/_GroupItem.html', 'collections/projects/groups'], function (ProjectGroupsTmpl, GroupCollection) { 
    var GroupItemView = Backbone.Marionette.ItemView.extend({ 
     tagName: 'li', 
     template: _.template(ProjectGroupsTmpl) 
    }); 
    var CompositeView = Backbone.Marionette.CompositeView.extend({ 
     template: _.template("<ul id='ulgroups' ></ul>"), 
     itemView: GroupItemView, 
     itemViewContainer: '#ulgroups', 
     initialize: function (params) { 
      this.isLoading = false; 
      this.ProjectID = params.id; 
      this.grpcollection = new GroupCollection([], { 
       queryParams: { 
        ProjectID: params.id 
       } 
      }); 
      this.collection = this.grpcollection.fullCollection; 
      this.getData(); 
      var self = this; 
      $(window).scroll(function() { 
       self.checkScroll(); 
      }); 
     }, 
     getData: function() { 
      var that = this; 
      this.isLoading = true; 
      this.grpcollection.fetch({ 
       success: function (collection, response, options) { 
        if (response.length > 0) { 
         that.isLoading = false; 
        } 
       } 
      }); 
     }, 
     getNextPage: function() { 
      var that = this; 
      this.isLoading = true; 
      this.grpcollection.getNextPage({ 
       success: function (collection, response, options) { 
        if (response.length > 0) { 
         that.isLoading = false; 
        } 
       } 
      }); 
     }, 
     checkScroll: function() { 
      var triggerPoint = 100; // 100px from the bottom 
      if (!this.isLoading && $(window).scrollTop() + $(window).height() + triggerPoint > $(document).height()) { 
       this.getNextPage(); 
      } 
     }, 
     appendHtml: function (collectionView, itemView, index) { 
      $(this.itemViewContainer).append(itemView.el); 
     } 
    }); 
    return CompositeView; 
}); 
1

페이지가 매겨진 요청마다 모델을 보유하기 위해 임시 컬렉션을 만들어 비슷한 문제를 해결했습니다. 그러나 데이터와보기를 협상하기 위해 Marionette 컨트롤러를 만들었 기 때문에 설정이 당신과 약간 다릅니다. 컨트롤러의 "show"메서드는 초기 데이터 요청을 처리하고 "showMore"메서드는 후속 요청을 처리했습니다. 기본적으로 내가 한 일은 다음과 같습니다.

(function ($, _, Backbone, Marionette) { 
    var carData = [ 
     { 
      make: 'Audi', 
      model: 'A4', 
      year: '1994' 
     }, 
     { 
      make: 'BMW', 
      model: '3 Series', 
      year: '1975' 
     }, 
     { 
      make: 'Chevrolet', 
      model: 'Cruze', 
      year: '2008' 
     }, 
     { 
      make: 'Daimler', 
      model: 'Six', 
      year: '1994' 
     }, 
     { 
      make: 'Fiat', 
      model: '500X', 
      year: '2015' 
     }, 
     { 
      make: 'Honda', 
      model: 'Civic', 
      year: '1972' 
     }, 
     { 
      make: 'Kia', 
      model: 'Optima', 
      year: '2015' 
     }, 
     { 
      make: 'Lada', 
      model: 'Priora', 
      year: '2007' 
     }, 
     { 
      make: 'Mitusbishi', 
      model: 'Lancer', 
      year: '1973' 
     }, 
     { 
      make: 'Nissan', 
      model: 'Pathfinder', 
      year: '1995' 
     } 
    ]; 
    var Car = Backbone.Model.extend({ 
     defaults: { 
      make: '', 
      model: '', 
      year: '' 
     } 
    }); 
    var Cars = Backbone.Collection.extend({ 
     model: Car, 
     rows: 3, 
     page: 0 
    }); 
    var CarView = Marionette.ItemView.extend({ 
     tagName: 'tr', 
     template: '#row-template' 
    }); 
    var CarsView = Marionette.CompositeView.extend({ 
     childView: CarView, 
     childViewContainer: 'tbody', 
     template: '#table-template', 
     triggers: { 
      'click button': 'showMore' 
     } 
    }); 
    var CarController = Marionette.Controller.extend({ 
     initialize: function (options) { 
      this.collection = options.collection; 
     }, 
     show: function() { 
      var cars = this.getData(this.collection.page); 
      var carsView = new CarsView({ 
       collection: new Backbone.Collection(cars) 
      }); 
      this.listenTo(carsView, 'showMore', this.showMore); 
      app.carsRegion.show(carsView); 
     }, 
     showMore: function (options) { 
      var cars = this.getData(++this.collection.page); 
      options.collection.add(cars); 
     }, 
     getData: function (page) { 
      var rows = this.collection.rows; 
      var start = page * rows; 
      var end = start + rows; 
      return this.collection.slice(start, end); 

     } 
    }); 
    var app = new Marionette.Application(); 
    var cars = new Cars(carData); 
    var carController = new CarController({ 
     collection: cars 
    }); 
    app.addRegions({ 
     carsRegion: '#cars-region' 
    }); 
    app.addInitializer(function() { 
     carController.show(); 
    }); 
    app.start(); 
}(jQuery, _, Backbone, Marionette)); 

이것은 JSFiddle으로도 제공됩니다.

+0

감사 스미스하지만, 뷰 자체 내부 수집을 가져하려는 경우 제안을해야합니까? –

+2

여전히 마스터 컬렉션 (GroupCollection)에서 모델을 가져올 수 있습니다. 각 가져 오기에서 관련 모델을 임시 컬렉션에 추가하는 것입니다. 임시 수집은 비어있는 채로 시작하여 데이터를 새로 추가 할 때마다 추가됩니다. 이해가 되니? 데이터 요청 및 뷰 작성을 관리하는 컨트롤러를 만드는 것이 좋습니다. IMO에 대한보다 명확한 분리를 만듭니다. –

관련 문제