서버에서 제공되는 다음 JSON이 있습니다. 이를 통해 중첩 모델이있는 모델을 만들고 싶습니다. 나는 이것을 달성하는 방법이 확실하지 않습니다.
//json
[{
name : "example",
layout : {
x : 100,
y : 100,
}
}]
다음과 같은 구조를 가진 두 개의 중첩 된 백본 모델로 변환되기를 원합니다.
// structure
Image
Layout
...
그래서 레이아웃 모델을 다음과 같이 정의합니다.
var Layout = Backbone.Model.extend({});
그러나 아래의 두 가지 (있는 경우) 기술 중 이미지 모델을 정의하는 데 사용해야하는 기술은 무엇입니까? 아래 A 또는 B?
ㅏ
var Image = Backbone.Model.extend({
initialize: function() {
this.set({ 'layout' : new Layout(this.get('layout')) })
}
});
또는 B
var Image = Backbone.Model.extend({
initialize: function() {
this.layout = new Layout( this.get('layout') );
}
});
답변
Backbone 응용 프로그램을 작성하는 동안 동일한 문제가 있습니다. 임베디드 / 중첩 모델을 처리해야합니다. 꽤 우아한 해결책이라고 생각했던 약간의 조정을했습니다.
예, 객체 주변의 속성을 변경하기 위해 구문 분석 방법을 수정할 수 있지만 실제로는 모두 유지 관리가 불가능한 코드 IMO이며 솔루션 이라기보다 해킹에 더 가깝습니다.
귀하의 예를 위해 제안하는 것은 다음과 같습니다.
먼저 레이아웃 모델을 이렇게 정의하십시오.
var layoutModel = Backbone.Model.extend({});
다음은 이미지 모델입니다.
var imageModel = Backbone.Model.extend({
model: {
layout: layoutModel,
},
parse: function(response){
for(var key in this.model)
{
var embeddedClass = this.model[key];
var embeddedData = response[key];
response[key] = new embeddedClass(embeddedData, {parse:true});
}
return response;
}
});
모델 자체를 변경하지 않고 단순히 parse 메서드에서 원하는 개체를 다시 전달합니다.
이렇게하면 서버에서 읽을 때 중첩 된 모델의 구조가 보장됩니다. 이제 저장 또는 설정이 실제로 처리되지 않는 것을 알 수 있습니다. 적절한 모델을 사용하여 중첩 된 모델을 명시 적으로 설정하는 것이 합리적이라고 생각하기 때문입니다.
이렇게 :
image.set({layout : new Layout({x: 100, y: 100})})
또한 다음을 호출하여 중첩 된 모델에서 실제로 parse 메서드를 호출하고 있음을 유의하십시오.
new embeddedClass(embeddedData, {parse:true});
model
필드에 필요한만큼 중첩 된 모델을 정의 할 수 있습니다 .
물론 중첩 된 모델을 자체 테이블에 저장하려는 경우에도 마찬가지입니다. 이것으로는 충분하지 않습니다. 그러나 객체 전체를 읽고 저장하는 경우이 솔루션으로 충분합니다.
답변
이 코드는 구문 분석을 재정의하라는 Peter Lyon의 제안의 예로 게시하고 있습니다. 나는 같은 질문이 있었고 이것은 나를 위해 일했습니다 (Rails 백엔드 사용). 이 코드는 Coffeescript로 작성되었습니다. 익숙하지 않은 사람들을 위해 몇 가지 사항을 명시했습니다.
class AppName.Collections.PostsCollection extends Backbone.Collection
model: AppName.Models.Post
url: '/posts'
...
# parse: redefined to allow for nested models
parse: (response) -> # function definition
# convert each comment attribute into a CommentsCollection
if _.isArray response
_.each response, (obj) ->
obj.comments = new AppName.Collections.CommentsCollection obj.comments
else
response.comments = new AppName.Collections.CommentsCollection response.comments
return response
또는 JS
parse: function(response) {
if (_.isArray(response)) {
return _.each(response, function(obj) {
return obj.comments = new AppName.Collections.CommentsCollection(obj.comments);
});
} else {
response.comments = new AppName.Collections.CommentsCollection(response.comments);
}
return response;
};
답변
백본 연관Backbone.AssociatedModel
에서 사용 :
var Layout = Backbone.AssociatedModel.extend({
defaults : {
x : 0,
y : 0
}
});
var Image = Backbone.AssociatedModel.extend({
relations : [
type: Backbone.One,
key : 'layout',
relatedModel : Layout
],
defaults : {
name : '',
layout : null
}
});
답변
Backbone 자체에 권장되는 방법이 있는지 잘 모르겠습니다. 레이아웃 개체가 백엔드 데이터베이스에 고유 한 ID와 레코드를 가지고 있습니까? 그렇다면 당신은 당신이 가지고있는 것처럼 그것을 자신의 모델로 만들 수 있습니다. 그렇지 않은 경우 중첩 된 문서로 남겨 둘 수 있으며 save
및 parse
메서드 에서 JSON과 올바르게 변환되었는지 확인하십시오 . 이와 같은 접근 방식을 취하면 A 예제가 set
제대로 업데이트 되기 때문에 백본과 더 일치 한다고 생각 attributes
하지만 Backbone이 기본적으로 중첩 모델로 무엇을하는지 확실하지 않습니다. 이를 처리하려면 사용자 지정 코드가 필요할 수 있습니다.
답변
단순하게 유지하려면 옵션 B를 선택하겠습니다.
또 다른 좋은 옵션은 Backbone-Relational 을 사용하는 것 입니다. 다음과 같이 정의하면됩니다.
var Image = Backbone.Model.extend({
relations: [
{
type: Backbone.HasOne,
key: 'layout',
relatedModel: 'Layout'
}
]
});
답변
중첩 된 모델과 속성에 Backbone DeepModel 플러그인을 사용합니다.
https://github.com/powmedia/backbone-deep-model
바인딩하여 이벤트를 n 레벨 깊이로 변경할 수 있습니다. 예를 들면 :
model.on('change:example.nestedmodel.attribute', this.myFunction);
답변
rycfung의 아름다운 대답 의 CoffeeScript 버전 :
class ImageModel extends Backbone.Model
model: {
layout: LayoutModel
}
parse: (response) =>
for propName,propModel of @model
response[propName] = new propModel( response[propName], {parse:true, parentModel:this} )
return response
달콤하지 않나요? 😉
