Backbone: λͺ¨λΈ λ‚΄λΆ€μ—μ„œ μ»¬λ ‰μ…˜μ„ λͺ¨λΈλ§ν•˜λŠ” κ°€μž₯ 쒋은 방법은 λ¬΄μ—‡μž…λ‹ˆκΉŒ?

에 λ§Œλ“  2010λ…„ 11μ›” 04일  Β·  11μ½”λ©˜νŠΈ  Β·  좜처: jashkenas/backbone

우리 νŒ€μ€ ν₯미둜운 데이터 μŠ€ν‚€λ§ˆλ‘œ μž‘μ—…ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€. 기본적으둜 μš°λ¦¬κ°€ 가지고 μžˆλŠ” 것은 이름과 버전, 그리고 그것에 μ†ν•˜λŠ” ν•­λͺ©λ“€μ˜ 배열이 μžˆλŠ” λ¬Έμ„œμž…λ‹ˆλ‹€. ν•­λͺ© μžμ²΄μ—λŠ” 더 큰 λͺ¨λΈμ— μ†ν•˜κΈ° λ•Œλ¬Έμ— μ—°κ²°λœ IDκ°€ μ—†μ§€λ§Œ κΈ°λ³Έ λ¬Έμ„œμ—μ„œ ν•­λͺ©μ„ μΆ”κ°€/νŽΈμ§‘/μ‚­μ œν•  수 μžˆμŠ΅λ‹ˆλ‹€. λͺ¨λΈμ€ λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.
{
이름: "ν…ŒμŠ€νŠΈ",
버전 : 1,
ν•­λͺ© : [
{이름: "ν•­λͺ© 1",
μœ„μΉ˜ : 0},
{이름: "ν•­λͺ© 2",
μœ„μΉ˜ : 1}]
}

λͺ¨λΈμ˜ κΈ°λ³Έ ν•­λͺ©μ— μ»¬λ ‰μ…˜μ„ μ‚¬μš©ν•˜λŠ” 것이 μ’‹μ§€λ§Œ μ»¬λ ‰μ…˜μ΄ μ—…λ°μ΄νŠΈλ  λ•Œλ§ˆλ‹€ λͺ¨λΈμ€ URLκ³Ό ν•¨κ»˜ μ„œλ²„μ— λ‹€μ‹œ κ²Œμ‹œν•΄μ•Ό ν•©λ‹ˆλ‹€. λ°±λ³Έμ—μ„œ 이것을 λͺ¨λΈλ§ν•˜λŠ” κ°€μž₯ 쒋은 방법은 λ¬΄μ—‡μž…λ‹ˆκΉŒ? 더 λ§Žμ€ 정보가 ν•„μš”ν•˜λ©΄ μš”μ μ— 더 많이 κ²Œμ‹œν•˜κ²Œ λ˜μ–΄ κΈ°μ©λ‹ˆλ‹€.

question

κ°€μž₯ μœ μš©ν•œ λŒ“κΈ€

@eranation : items λ₯Ό μœ μ§€ν•˜λŠ” 것을 μ’‹μ•„ν•˜λ―€λ‘œ 동기화λ₯Ό μœ μ§€ν•  ν•„μš”κ°€ μ—†μŠ΅λ‹ˆλ‹€. 이λ₯Ό μœ„ν•΄μ„œλŠ” ꡬ문 뢄석을 μœ„ν•΄ μ‘λ‹΅μ—μ„œ items 개체λ₯Ό 가져와 직렬화λ₯Ό μœ„ν•΄ λ‹€μ‹œ μΆ”κ°€ν•΄μ•Ό ν•©λ‹ˆλ‹€(μ•„λž˜ μ°Έμ‘°). κ·Έ 외에도 @rsim 이 constructor λ©”μ„œλ“œμ— initialize 에 넣은 논리λ₯Ό λŒ€μ‹  λ„£κ³  on λŒ€μ‹  bind (반쯀 지원 쀑단됨).

κ°€λŠ₯ν•œ 경우 속성을 얕은 ν•΄μ‹œ(μ€‘μ²©λœ μ»¬λ ‰μ…˜, λͺ¨λΈ λ“± μ—†μŒ)둜 λ§Œλ“œλŠ” 것이 훨씬 μ‰½λ‹€λŠ” 것을 μ•Œμ•˜μŠ΅λ‹ˆλ‹€.

var Document = Backbone.Model.extend({
  constructor: function() {
    this.items = new ItemSet(null, {document: this});
    this.items.on('change', this.save, this);
    Backbone.Model.apply(this, arguments);
  },
  parse: function(resp) {
    this.items.set(resp.items, {parse: true, remove: false});
    delete resp.items;
    return resp;
  },
  toJSON: function() {
    var attrs = _.clone(this.attributes);
    attrs.items = this.items.toJSON();
    return attrs;
  }
});
var ItemSet = Backbone.Collection.extend({
  model: Item,
  initialize: function(models, options) {
    this.document = options.document;
  }
});
var Item = Backbone.Model.extend({
  // access document with this.collection.document
});
var document1 = new Document({
  name: "Test",
  version: 1,
  items: [
    {name : "Item 1", position : 0},
    {name : "Item 2", position : 1}
  ]
});

이것은 깊이 μ€‘μ²©λœ μŠ€ν‚€λ§ˆμ—μ„œλ„ 잘 μž‘λ™ν•˜λŠ” 것 κ°™μŠ΅λ‹ˆλ‹€. ( λ¬Έμ„œ μ°Έμ‘°)

λͺ¨λ“  11 λŒ“κΈ€

두 가지 μ£Όμš” μ˜΅μ…˜μ΄ μžˆμŠ΅λ‹ˆλ‹€. 첫 λ²ˆμ§ΈλŠ” ν•­λͺ©μ„ 바닐라 μ†μ„±μœΌλ‘œ λ‘λŠ” κ²ƒμž…λ‹ˆλ‹€. 백본은 속성이 변경될 λ•Œ 심측 동등 검사λ₯Ό μ‚¬μš©ν•˜λ―€λ‘œ λ‚΄λΆ€ ν•­λͺ©μ΄ μ—…λ°μ΄νŠΈλ˜λ©΄ λ¬Έμ„œμ—μ„œ 이에 λŒ€ν•΄ μ•Œ 수 μžˆμŠ΅λ‹ˆλ‹€.

λ‹€λ₯Έ μ˜΅μ…˜μ€ λ¬Έμ„œμ—μ„œ ν•­λͺ©μ„ 가져와 λ¬Έμ„œμ— κ³ μ •λœ μ»¬λ ‰μ…˜ λ‚΄λΆ€μ—μ„œ 자체적으둜 λͺ¨λΈλ‘œ μ²¨λΆ€ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€(DocumentCloudμ—μ„œ μ΄λŸ¬ν•œ 행을 따라 μž‘μ—…μ„ μˆ˜ν–‰ν•©λ‹ˆλ‹€). 예λ₯Ό λ“€μ–΄(λŒ€λž΅μ μœΌλ‘œ):

var Document = Backbone.Model.extend({
  initialize: function() {
    this.items = new ItemSet();
    this.items.bind('change', this.save);
  }
});

λ‘˜ 쀑 ν•˜λ‚˜κ°€ 당신을 μœ„ν•΄ 잘 μž‘λ™ν•©λ‹ˆκΉŒ?

λ˜ν•œ ν•­λͺ©μ—μ„œ ν•„μš”ν•  λ•Œ μ•‘μ„ΈμŠ€ν•  수 μžˆλŠ” Document κ°œμ²΄μ— "document" 속성을 λ‹€μ‹œ μΆ”κ°€ν•˜λŠ” 것이 μ’‹μŠ΅λ‹ˆλ‹€.

var Document = Backbone.Model.extend({
  initialize: function() {
    this.items = new ItemSet(this.get('items'), {document: this});
    this.items.bind('change', this.save);
  }
});
var ItemSet = Backbone.Collection.extend({
  initialize: function(models, options) {
    this.document = options.document;
  }
});
var Item = Backbone.Model.extend({
  // access document with this.collection.document
});
var document1 = new Document({
  name: "Test",
  version: 1,
  items: [
    {name : "Item 1", position : 0},
    {name : "Item 2", position : 1}
  ]
});

ν•­λͺ©μ˜ λ³€κ²½ 이벀트λ₯Ό λ¬Έμ„œ μ €μž₯에 λ°”μΈλ”©ν•˜λŠ” 것이 λˆ„λ½λœ 뢀뢄이라고 μƒκ°ν•©λ‹ˆλ‹€. ν•˜μ§€λ§Œ ItemSet에 λ¬Έμ„œλ₯Ό μΆ”κ°€ν•˜λŠ” 것도 맀우 도움이 될 것 κ°™μŠ΅λ‹ˆλ‹€. μš°λ¦¬λŠ” 였늘 이것을 μ‹œλ„ν•˜κ³  μ—¬λŸ¬λΆ„μ—κ²Œ 그것이 μ–΄λ–»κ²Œ λ‚˜νƒ€λ‚˜λŠ”μ§€ μ•Œλ €μ€„ κ²ƒμž…λ‹ˆλ‹€.

이것은 잘 μž‘λ™ν–ˆμŠ΅λ‹ˆλ‹€. ν˜„μž¬ μš°λ¦¬κ°€ κ²ͺκ³  μžˆλŠ” κ°€μž₯ 큰 λ¬Έμ œλŠ” λͺ½κ³ μ΄λ“œμ— κ΄€ν•œ κ²ƒμž…λ‹ˆλ‹€. 도움을 μ£Όμ…”μ„œ κ°μ‚¬ν•©λ‹ˆλ‹€.

λͺ¨λ“  ν•­λͺ©μ„ ν•œ λ²ˆμ— μ €μž₯ν•˜λ €λ©΄ μ–΄λ–»κ²Œ ν•΄μ•Ό ν•©λ‹ˆκΉŒ? ν•­λͺ©μ΄ 변경될 λ•Œλ§ˆλ‹€ μš”μ²­ν•˜κ³  싢지 μ•Šμ§€λ§Œ μ‚¬μš©μžμ˜ μž‘μ—…μ— λŒ€ν•œ 단일 μš”μ²­μœΌλ‘œ λͺ¨λ‘ μ €μž₯ν•˜κ³  μ‹ΆμŠ΅λ‹ˆλ‹€. λ¬Έμ„œκ°€ μ €μž₯될 λ•Œ λͺ¨λ“  것을 μˆ˜μ§‘ν•˜κ³  λ¬Έμ„œμ˜ 'ν•­λͺ©' 속성을 μ—…λ°μ΄νŠΈν•˜λŠ” 것에 λŒ€ν•΄ μƒκ°ν•˜κ³  μžˆμ—ˆμŠ΅λ‹ˆλ‹€. 쒋은 ν•΄κ²°μ±…μž…λ‹ˆκΉŒ?

ν•­λͺ©μ΄ λ¬Έμ„œμ— μ„€μ •λ˜μ–΄ μžˆλŠ” ν•œ document.save()λ₯Ό μˆ˜ν–‰ν•˜λ©΄ ν•­λͺ©λ„ μ„œλ²„λ‘œ μ „μ†‘λ©λ‹ˆλ‹€.

κ·ΈλŸ¬λ‚˜ λŸ°νƒ€μž„μ— document1.items μ»¬λ ‰μ…˜μ— ν•­λͺ©μ„ μΆ”κ°€ν•˜λ©΄ document1의 'items' 속성에도 μžλ™μœΌλ‘œ μΆ”κ°€λ˜μ§€ μ•ŠλŠ”λ‹€κ³  κ°€μ •ν•΄ λ³΄κ² μŠ΅λ‹ˆλ‹€. λ”°λΌμ„œ document1.save()λ₯Ό μˆ˜ν–‰ν•˜λ©΄ μ»¬λ ‰μ…˜μ— μΆ”κ°€ν•œ μƒˆ λͺ¨λΈμ΄ μ„œλ²„λ‘œ μ „μ†‘λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. μ»¬λ ‰μ…˜μ— λŒ€ν•œ λ³€κ²½ 사항이 μ €μž₯κ³Ό ν•¨κ»˜ μ „μ†‘λœ λͺ¨λΈμ˜ μ†μ„±μ—μ„œ μ–΄λ–»κ²Œ μ „νŒŒλ  수 μžˆλŠ”μ§€ μ•Œ 수 μ—†μŠ΅λ‹ˆλ‹€.

λ”°λΌμ„œ 이λ₯Ό μ²˜λ¦¬ν•˜λŠ” 방법은 λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€. λ¬Έμ„œμ—λŠ” κΈ°λ³Έ ν•­λͺ© 배열이 μžˆμŠ΅λ‹ˆλ‹€. μ΄ˆκΈ°ν™” μ‹œ μ˜€λ²„λ‘œλ“œλœ 집합 λ©”μ„œλ“œμ—μ„œ μ†μ„±μ—μ„œ μƒˆ ν•­λͺ© μ»¬λ ‰μ…˜μ„ λ§Œλ“€κ³  λ¬Έμ„œμ— μ„€μ •ν•©λ‹ˆλ‹€.

class Document extends Backbone.Model
  defaults:
    items: []

  set: (attrs, options) ->
    items = attrs['items']
    if _( items ).isArray()
      if _( items ).isEmpty()
        attrs['items'] = new DocumentItemsCollection
        newItem = new Item
        attrs['items'].add(newItem, { silent: true })
      else
        attrs['items'] = new DocumentItemsCollection items

κ·Έ μ‹œμ μ—μ„œ 'get', 'set', 'add' 및 'remove'λ₯Ό μ‚¬μš©ν•˜μ—¬ ν•­λͺ© μˆ˜μ§‘ 방법을 μ²˜λ¦¬ν•˜λ©΄ λ©λ‹ˆλ‹€. 점 ν‘œκΈ°λ²•μ„ ν˜Όλ™ν•˜μ§€ λ§ˆμ‹­μ‹œμ˜€. λ¬Έμ„œ μžμ²΄μ—μ„œ λ³€κ²½ 이벀트λ₯Ό λ°œμƒμ‹œν‚€λŠ” addItem 및 deleteItemμ΄λΌλŠ” λ©”μ„œλ“œκ°€ λ‚΄ Document ν΄λž˜μŠ€μ— μžˆμŠ΅λ‹ˆλ‹€. λ¬Έμ„œμ—μ„œ save()λ₯Ό μˆ˜ν–‰ν•˜λ©΄ ν•­λͺ© μ»¬λ ‰μ…˜μ—μ„œ toJSON을 ν˜ΈμΆœν•©λ‹ˆλ‹€.

μ†”μ§νžˆ 이것은 우리 λ¬Έμ„œμ˜ λ‹¨μˆœν•œ 경우이며 더 κΉŠμ€ ν•˜μœ„ λ¬Έμ„œκ°€ μžˆμŠ΅λ‹ˆλ‹€. 백본으둜 이 μ •λ„μ˜ λ³΅μž‘μ„±μ„ μ²˜λ¦¬ν•˜κ³  λͺ¨λΈμ— μ—¬λŸ¬ λ©”μ„œλ“œλ₯Ό μ˜€λ²„λ‘œλ“œν•˜λŠ” 것은 정말 골치 μ•„ν”ˆ μΌμž…λ‹ˆλ‹€. μš°λ¦¬λŠ” 이제 백본을 λ―Έλž˜μ— μƒˆμ‹Ή μ½”μ–΄λ‘œ κ΅μ²΄ν•˜λŠ” 것을 κ³ λ €ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.

정말 λ³΅μž‘ν•œ λ¬Έμ„œλ₯Ό μ²˜λ¦¬ν•΄μ•Ό ν•˜λŠ” 경우 ExtJS λ˜λŠ” μƒˆμ‹Ή μ½”μ–΄λ₯Ό μ‚΄νŽ΄λ³΄λŠ” 것이 μ’‹μŠ΅λ‹ˆλ‹€. 백본은 κ°„λ‹¨ν•œ λͺ¨λΈμ΄ μžˆλŠ” μ†Œκ·œλͺ¨ ν”„λ‘œμ νŠΈμ— μ ν•©ν•˜μ§€λ§Œ 개체/μƒν˜Έμž‘μš©μ΄ μ¦κ°€ν•˜κΈ° μ‹œμž‘ν•˜λ©΄ κ½€ 빨리 λΆ„ν•΄λ©λ‹ˆλ‹€.

1.0에 λŒ€ν•œ μƒˆλ‘œμš΄ "λͺ¨λ²” 사둀"κ°€ μžˆμŠ΅λ‹ˆκΉŒ?

@eranation : items λ₯Ό μœ μ§€ν•˜λŠ” 것을 μ’‹μ•„ν•˜λ―€λ‘œ 동기화λ₯Ό μœ μ§€ν•  ν•„μš”κ°€ μ—†μŠ΅λ‹ˆλ‹€. 이λ₯Ό μœ„ν•΄μ„œλŠ” ꡬ문 뢄석을 μœ„ν•΄ μ‘λ‹΅μ—μ„œ items 개체λ₯Ό 가져와 직렬화λ₯Ό μœ„ν•΄ λ‹€μ‹œ μΆ”κ°€ν•΄μ•Ό ν•©λ‹ˆλ‹€(μ•„λž˜ μ°Έμ‘°). κ·Έ 외에도 @rsim 이 constructor λ©”μ„œλ“œμ— initialize 에 넣은 논리λ₯Ό λŒ€μ‹  λ„£κ³  on λŒ€μ‹  bind (반쯀 지원 쀑단됨).

κ°€λŠ₯ν•œ 경우 속성을 얕은 ν•΄μ‹œ(μ€‘μ²©λœ μ»¬λ ‰μ…˜, λͺ¨λΈ λ“± μ—†μŒ)둜 λ§Œλ“œλŠ” 것이 훨씬 μ‰½λ‹€λŠ” 것을 μ•Œμ•˜μŠ΅λ‹ˆλ‹€.

var Document = Backbone.Model.extend({
  constructor: function() {
    this.items = new ItemSet(null, {document: this});
    this.items.on('change', this.save, this);
    Backbone.Model.apply(this, arguments);
  },
  parse: function(resp) {
    this.items.set(resp.items, {parse: true, remove: false});
    delete resp.items;
    return resp;
  },
  toJSON: function() {
    var attrs = _.clone(this.attributes);
    attrs.items = this.items.toJSON();
    return attrs;
  }
});
var ItemSet = Backbone.Collection.extend({
  model: Item,
  initialize: function(models, options) {
    this.document = options.document;
  }
});
var Item = Backbone.Model.extend({
  // access document with this.collection.document
});
var document1 = new Document({
  name: "Test",
  version: 1,
  items: [
    {name : "Item 1", position : 0},
    {name : "Item 2", position : 1}
  ]
});

이것은 깊이 μ€‘μ²©λœ μŠ€ν‚€λ§ˆμ—μ„œλ„ 잘 μž‘λ™ν•˜λŠ” 것 κ°™μŠ΅λ‹ˆλ‹€. ( λ¬Έμ„œ μ°Έμ‘°)

@akre54 κ°μ‚¬ν•©λ‹ˆλ‹€, 이것은 쒋은 μ˜ˆμž…λ‹ˆλ‹€. λŒ€λ‹¨νžˆ κ°μ‚¬ν•©λ‹ˆλ‹€.

이 νŽ˜μ΄μ§€κ°€ 도움이 λ˜μ—ˆλ‚˜μš”?
0 / 5 - 0 λ“±κΈ‰