여러 모델 하위 클래스의 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.Collection
는 Logbook
JSON 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
'UFO ET IT' 카테고리의 다른 글
JPA Hibernate를 사용하여 자동으로 자식 개체 저장 (0) | 2020.11.24 |
---|---|
MySQL의 DOUBLE 대 DECIMAL (0) | 2020.11.24 |
자바 동기화 목록 (0) | 2020.11.24 |
nodejs 요청 모듈에서 리디렉션 된 URL을 어떻게 얻습니까? (0) | 2020.11.24 |
Android Studio를 사용하여 코드 커버리지를 얻는 방법은 무엇입니까? (0) | 2020.11.24 |