[jquery] Backbone.js-Backbone.sync 또는 jQuery.ajax에 전체 컬렉션을 저장하는 방법은 무엇입니까?

나는 그것을 할 수 있다는 것을 잘 알고 있으며 꽤 많은 곳을 살펴 보았습니다 (포함 : 전체 컬렉션 저장을위한 모범 사례? ). 하지만 여전히 “정확히 어떻게”코드로 작성되었는지 확실하지 않습니다. (게시물은 영어로 설명합니다. 자바 스크립트에 대한 설명이 있으면 좋겠습니다. 🙂

모델 컬렉션이 있다고 가정 해 보겠습니다. 모델 자체에 중첩 컬렉션이있을 수 있습니다. 부모 컬렉션의 toJSON () 메서드를 재정의했으며 유효한 JSON 개체를 얻고 있습니다. 전체 컬렉션 (해당 JSON)을 “저장”하고 싶지만 백본에는 해당 기능이 내장되어 있지 않은 것 같습니다.

var MyCollection = Backbone.Collection.extend({
model:MyModel,

//something to save?
save: function() {
   //what to write here?
 }

});

나는 당신이 말해야 할 곳을 알고 있습니다.

Backbone.sync = function(method, model, options){
/*
 * What goes in here?? If at all anything needs to be done?
 * Where to declare this in the program? And how is it called?
 */
}

처리와 함께 ‘보기’가 완료되면 컬렉션이 서버에 자신을 “저장”하도록 지시하는 역할을합니다 (대량 업데이트 / 생성 요청 처리 가능).

발생하는 질문 :

  1. “모두 함께 연결”하기 위해 코드를 작성하는 방법 / 무엇입니까?
  2. 콜백의 ‘올바른’위치는 무엇이며 “성공 / 오류”콜백을 지정하는 방법은 무엇입니까? 내 말은 문법적으로? 백본에 콜백을 등록하는 구문이 명확하지 않습니다 …

실제로 까다로운 작업이라면 뷰 내에서 jQuery.ajax를 호출 하고 성공 / 오류 콜백으로 this.successMethod또는 전달할 수 있습니까 this.errorMethod?? 작동할까요?

백본의 사고 방식과 일치해야합니다. 전체 컬렉션을 동기화하는 것이 확실히 누락 된 것을 알고 있습니다.



답변

내 즉각적인 생각은 Backbone.Collection의 save 메서드에 대한 메서드를 재정의하는 것이 아니라 컬렉션을 다른 Backbone.Model에 래핑하고 toJSON 메서드를 재정의하는 것입니다. 그러면 Backbone.js는 모델을 단일 리소스로 취급하므로 backone이 너무 많이 생각하는 방식을 해킹 할 필요가 없습니다.

Backbone.Collection에는 toJSON 메서드가 있으므로 대부분의 작업이 수행됩니다. 래퍼 Backbone.Model의 toJSON 메서드를 Backbone.collection에 프록시하면됩니다.

var MyCollectionWrapper = Backbone.Model.extend({
url: "/bulkupload",

//something to save?
toJSON: function() {
    return this.model.toJSON(); // where model is the collection class YOU defined above
 }

});


답변

아주 간단합니다 …

Backbone.Collection.prototype.save = function (options) {
    Backbone.sync("create", this, options);
};

… 컬렉션에 저장 방법을 제공합니다. 변경 사항에 관계없이 항상 모든 컬렉션의 모델을 서버에 게시합니다. 옵션은 일반적인 jQuery ajax 옵션입니다.


답변

나는 ‘save’와 같은 메소드를 가지게되었고 그 안에서 $ .ajax를 호출했습니다. @brandgonesurfing이 제안한대로 래퍼 클래스를 추가 할 필요없이 더 많은 제어권을 얻었습니다 (아이디어를 절대적으로 좋아하지만 🙂 이미 collection.toJSON () 메서드를 재정의했기 때문에 언급했듯이 모든 작업을 수행하는 것입니다. 아약스 호출에서 …

이것이 그것을 우연히 발견하는 사람에게 도움이되기를 바랍니다 …


답변

이것은 실제로 클라이언트와 서버 간의 계약에 따라 다릅니다. 다음은 PUT to /parent/:parent_id/childrenwith {"children":[{child1},{child2}]}가 부모의 자식을 PUT에 있는 것으로 대체하고 반환 하는 간단한 CoffeeScript 예제입니다 {"children":[{child1},{child2}]}.

class ChildElementCollection extends Backbone.Collection
  model: Backbone.Model
  initialize: ->
    @bind 'add', (model) -> model.set('parent_id', @parent.id)

  url: -> "#{@parent.url()}/children" # let's say that @parent.url() == '/parent/1'
  save: ->
    response = Backbone.sync('update', @, url: @url(), contentType: 'application/json', data: JSON.stringify(children: @toJSON()))
    response.done (models) => @reset models.children
    return response

이것은 매우 간단한 예입니다. 더 많은 작업을 수행 할 수 있습니다. 실제로 save ()가 실행될 때 데이터가 어떤 상태인지, 서버로 전달하기 위해 필요한 상태가 무엇인지, 서버가 제공하는 내용에 따라 다릅니다. 뒤.

서버가 PUT로 [{child1},{child2]정상이면 Backbone.sync 행이 response = Backbone.sync('update', @toJSON(), url: @url(), contentType: 'application/json').


답변

대답은 서버 측에서 컬렉션으로 수행하려는 작업에 따라 다릅니다.

게시물과 함께 추가 데이터를 보내야 하는 경우 래퍼 모델 또는 관계형 모델 이 필요할 수 있습니다 .

으로 래퍼 모델 당신은 항상 당신의 자신의 작성해야 구문 분석 방법 :

var Occupants = Backbone.Collection.extend({
    model: Person
});

var House = Backbone.Model.extend({
    url: function (){
        return "/house/"+this.id;
    },
    parse: function(response){
        response.occupants = new Occupants(response.occupants)
        return response;
    }
});

관계형 모델 은 더 쉽게 구성 할 수 있고나머지 서비스로 보내는 json에 속성을 넣을 includeInJSON 옵션으로조절할수 있기 때문에 더 좋습니다.

var House = Backbone.RelationalModel.extend({
    url: function (){
        return "/house/"+this.id;
    },
    relations: [
        {
            type: Backbone.HasMany,
            key: 'occupants',
            relatedModel: Person,
            includeInJSON: ["id"],
            reverseRelation: {
                key: 'livesIn'
            }
        }
    ]
});

추가 데이터를 보내지 않으면 컬렉션 자체를 동기화 할 수 있습니다 . 이 경우 컬렉션 (또는 컬렉션 프로토 타입)에 저장 메서드 를 추가해야합니다 .

var Occupants = Backbone.Collection.extend({
    url: "/concrete-house/occupants",
    model: Person,
    save: function (options) {
        this.sync("update", this, options);
    }
});


답변

또한 Backbone 컬렉션에 내장 저장 기능이 없다는 사실에 놀랐습니다. 이를 위해 백본 컬렉션에 넣은 내용은 다음과 같습니다. 컬렉션의 각 모델을 반복하고 독립적으로 저장하고 싶지는 않습니다. 또한 Node를 사용하는 백엔드에서 Backbone을 사용하고 있으므로 네이티브 Backbone.sync를 재정 의하여 소규모 프로젝트의 플랫 파일에 저장하지만 코드는 거의 동일해야합니다.

    save: function(){
      Backbone.sync('save', this, {
        success: function(){
          console.log('users saved!');
        }
      });
    }


답변

내가 아는 오래된 스레드는 다음과 같습니다.

Backbone.Collection.prototype.save = function (options) {
            // create a tmp collection, with the changed models, and the url
            var tmpCollection = new Backbone.Collection( this.changed() );
            tmpCollection.url = this.url;
            // sync
            Backbone.sync("create", tmpCollection, options);
        };
        Backbone.Collection.prototype.changed = function (options) {
            // return only the changed models.
            return this.models.filter( function(m){
                return m.hasChanged()
            });
        };
// and sync the diffs.
self.userCollection.save();

앞쪽으로 꽤 긴장 🙂