UFO ET IT

여러 모델 하위 클래스의 Backbone.js 컬렉션

ufoet 2020. 11. 24. 20:40
반응형

여러 모델 하위 클래스의 Backbone.js 컬렉션


"로그 북"목록을 반환하는 REST Json API가 있습니다. 다르지만 유사한 동작을 구현하는 많은 유형의 로그 북이 있습니다. 데이터베이스 계층에서 서버 측 구현은 일종의 단일 테이블 상속이므로 로그 북의 각 JSON 표현에는 "유형"이 포함됩니다.

[
  {"type": "ULM", "name": "My uml logbook", ... , specific_uml_logbook_attr: ...},
  {"type": "Plane", "name": "My plane logbook", ... , specific_plane_logbook_attr: ...}
]

이 서버 모델을 클라이언트 측에 복제 Logbook하고 싶으 므로 기본 클래스와 여러 로그 북 하위 클래스가 있습니다.

class Logbook extends Backbone.Model

class UmlLogbook extends Logbook

class PlaneLogbook extends Logbook

...

My Backbone.CollectionLogbookJSON API를 쿼리하는 데 사용하는 모델 집합입니다 .

class LogbookCollection extends Backbone.Collection
  model: Logbook
  url: "/api/logbooks"

로그 북 컬렉션을 가져올 때 각각 Logbook해당하는 하위 클래스 (JSON "type"속성을 기반 으로 함)로 캐스팅하는 방법이 있습니까?


실제로 있습니다.

컬렉션에 대해 'fetch'를 호출하면 컬렉션에 추가하기 전에 Backbone.Collection.parse를 통해 응답을 전달합니다.

'parse'의 기본 구현은 응답을 그대로 전달하지만 컬렉션에 추가 할 모델 목록을 반환하도록 재정의 할 수 있습니다.

class Logbooks extends Backbone.Collection

  model: Logbook

  url: 'api/logbooks'

  parse: (resp, xhr) ->
    _(resp).map (attrs) ->
      switch attrs.type
        when 'UML' then new UmlLogbook attrs
        when 'Plane' then new PLaneLogbook attrs

편집 : 워, idbentley가 나보다 먼저 거기에 도착했습니다. 유일한 차이점은 그가 '각각'을 사용하고 나는 '지도'를 사용했다는 것입니다. 둘 다 작동하지만 다르게 작동합니다.

'each'를 사용하면 '가져 오기'호출이 시작된 체인이 효과적으로 끊어지고 ( 'undefined'를 반환하여 'reset'(또는 'add')에 대한 후속 호출이 아무 작업도 수행하지 않음) 구문 분석에서 바로 모든 처리를 수행합니다. 함수.

'맵'을 사용하면 속성 목록을 모델 목록으로 변환하고 이미 작동중인 체인으로 다시 전달합니다.

다른 스트로크.

다시 편집 :이 작업을 수행하는 또 다른 방법이 있다는 것을 깨달았습니다.

컬렉션의 'model'속성은 'add', 'create'또는 'reset'에 속성이 전달되면 새 모델을 만드는 방법 만 알 수 있습니다. 따라서 다음과 같이 할 수 있습니다.

class Logbooks extends Backbone.Collection

  model: (attrs, options) ->
    switch attrs.type
      when 'UML' then new UmlLogbook attrs, options
      when 'Plane' then new PLaneLogbook attrs, options
      # should probably add an 'else' here so there's a default if,
      # say, no attrs are provided to a Logbooks.create call

  url: 'api/logbooks'

이것의 장점은 컬렉션이 이제 '가져 오기'이외의 작업을 위해 Logbook의 올바른 하위 클래스를 '캐스트'하는 방법을 알고 있다는 것입니다.


예. parse컬렉션 함수를 재정의 할 수 있습니다 (제가 알고있는 내용이기 때문에 coffeescript 대신 javascript를 사용할 것입니다. 그러나 매핑은 쉬워야합니다).

LogbookCollection = Backbone.Collection.extend({
    model: Logbook,
    url: "/api/logbooks",
    parse: function(response){
      var self = this;
      _.each(response, function(logbook){
          switch(logbook.type){
             case "ULM":
               self.add(new UmlLogBook(logbook);
               break;
             case "Plane":
               ...
          }
      }
    }
 });

도움이 되었기를 바랍니다.


백본 0.9.1부터 esa-matti suuronen의 pull-request에 설명 된 방법을 사용하기 시작했습니다.

https://github.com/documentcloud/backbone/pull/1148

after applying the patch, your collection would be something like this:

LogbookCollection = Backbone.Collection.extend({

    model: Logbook,

    createModel: function (attrs, options) {
        if (attrs.type === "UML") { // i'am assuming ULM was a typo
            return new UmlLogbook(attrs, options);
        } else if (attrs.type === "Plane") {
            return new Plane(attrs, options);
        } else {
            return new Logbook(attrs, options);
            // or throw an error on an unrecognized type
            // throw new Error("Bad type: " + attrs.type);
        }
    }

});

i believe this would fit since you're using STI (all models have unique ids)


parse can work on its own, or you could use the submodelTypes feature of Backbone-Relational.


Maybe it's bad to use eval, but this is much more ruby-style way (coffeescript):

  parse: (resp)->
    _(resp).map (attrs) ->
      eval("new App.Models.#{attrs.type}(attrs)")

So you don't need to write a lot of switch/cases, just set type attribute in your JSON. It works very good with rails+citier or other multitable inheritance solution. You can add new descendants without adding them to your cases.

And you can use such constructions in other places where you need a lot of switch/cases depending on your model class.

참고URL : https://stackoverflow.com/questions/6933524/a-backbone-js-collection-of-multiple-model-subclasses

반응형