Nice programing

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

nicepro 2020. 10. 5. 20:52
반응형

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();

앞쪽으로 꽤 긴장 :)


다음은 간단한 예입니다.

var Books = Backbone.Collection.extend({
model: Book,
url: function() {
  return '/books/';
},
save: function(){
  Backbone.sync('create', this, {
    success: function() {
      console.log('Saved!');
    }
  });
 }
});

컬렉션에서 save () 메서드를 호출하면 정의 된 URL로 PUT 메서드 요청을 보냅니다.


나는 다음과 같은 것을 시도 할 것입니다.

var CollectionSync = function(method, model, [options]) {
    // do similar things to Backbone.sync
}

var MyCollection = Backbone.Collection.extend({
    sync: CollectionSync,
    model: MyModel,
    getChanged: function() {
        // return a list of models that have changed by checking hasChanged()
    },
    save: function(attributes, options) {
        // do similar things as Model.save
    }
});

( https://stackoverflow.com/a/11085198/137067 )


The accepted answer is pretty good, but I can go one step further and give you code that will ensure the proper events are fired for your listeners while also allowing you to pass in option ajax event callbacks:

save: function( options ) {
  var self = this;

  var success = options.success;
  var error = options.error;
  var complete = options.complete;

  options.success = function( response, status, xhr ) {
    self.trigger('sync', self, response, options);
    if (success) return success.apply(this, arguments);
  };

  options.error = function( response, status, xhr ) {
    self.trigger('error', self, response, options);
    if (error) return error.apply(this, arguments);
  };

  options.complete = function( response, status, xhr ) {
    if (complete) return complete.apply(this, arguments);
  }

  Backbone.sync('create', this, options);
}

For anyone who is still using backbone.js in 2017, the accepted answer is not working.

Try removing the toJSON() override in the wrapper model and calling toJSON on the collection when you instantiate the model wrapper.

new ModelWrapper(Collection.toJSON());

참고URL : https://stackoverflow.com/questions/6879138/how-to-save-an-entire-collection-in-backbone-js-backbone-sync-or-jquery-ajax

반응형