【问题标题】:Proper way of updating js-data relation objects更新 js-data 关系对象的正确方法
【发布时间】:2016-05-31 09:45:33
【问题描述】:

我有一个相同类型对象的链表:

GET /cards.json

[{
  "id": 1,
  "lesserCardId": null,
  "greaterCardId": 2,
 }, {
  "id": 2,
  "lesserCardId": 1,
  "greaterCardId": 3
}, {
  "id": 3,
  "lesserCardId": 2,
  "greaterCardId": null
}]

资源定义:

DS.defineResource({
  name: 'card',
  relations: {
    belongsTo: {
      card: [{
        localField: 'lesserCard',
        localKey: 'lesserCardId'
      }, {
        localField: 'greaterCard',
        localKey: 'greaterCardId'
      }]
    }
  }
});

js-data 正确读取 json 并创建对象层次结构。我接下来想要的是自动更新链接的卡片属性,如下所示:

var card1 = DS.get('card', 1);
var card4 = DS.inject('card', {'id': 4});
card1.greaterCard = card4;

// corresponding liked object properties should be updated automatically
expect(card4.lesserCard).toBe(card1);
expect(card2.lesserCard).toBeUndefined();

我已经实现了这一点,而无需像这样制作自定义 setter 的 js-data:

Object.defineProperty(Card.prototype, 'greaterCard', {
  set: function (card) {
     // custom logic for updating linked list structure
     if (card === this.$greaterCard) {
       return;
     }
     this.$greaterCard.lesserCard = this.$lesserCard;
     this.$greaterCard = card;
     if (card) {
       card.lesserCard = this;
     }
     // updating depending properties
     this.$updateCardLevel();
     this.$updateCardLevelMax();
  },
  get: function () {
    return this.$greaterCard;
  }
});

但是 js-data 为关系对象引入了它自己的属性描述符。所以不能应用这种方法。我还没有找到一种方法来挂钩 js-data 关系属性设置器。我可以使用cardService.setGreaterCard(card, greaterCard); 之类的方法创建一个单独的服务,它会更新列表结构,但这不会那么方便。有没有更好的方法在属性更改时更新链接对象?

js-data 版本:2.9.0

【问题讨论】:

  • 作为解决方案添加了card.setLesserCard(card);card.setGreaterCard(card);。不漂亮,但有效。

标签: javascript jsdata


【解决方案1】:

在 JSData 2.x 中你会这样做:

var Card = DS.defineResource({
  name: 'card',
  relations: {
    belongsTo: {
      card: [
        {
          localField: 'lesserCard',
          localKey: 'lesserCardId',
          link: false
        },
        {
          localField: 'greaterCard',
          localKey: 'greaterCardId',
          link: false
        }
      ]
    }
  }
});

Object.defineProperties(Card[Card.class].prototype, {
  lesserCard: {
    set: function (lesserCard) {
       this.lesserCardId = lesserCard.id;
       lesserCard.greaterCardId = this.id;
    },
    get: function () {
      return Card.get(this.lesserCardId);
    }
  },
  greaterCard: {
    set: function (greaterCard) {
       this.greaterCardId = greaterCard.id;
       greaterCard.lesserCardId = this.id;
    },
    get: function () {
      return Card.get(this.greaterCardId);
    }
  }
});

在 JSData 3.x 中,您只需这样做:

store.defineMapper('card', {
  relations: {
    belongsTo: {
      card: [
        {
          localField: 'lesserCard',
          foreignKey: 'lesserCardId',
          set: function (Relation, card, lesserCard, originalSet) {
            lesserCard.greaterCardId = card.id;
            originalSet(lesserCard);
          }
        },
        {
          localField: 'greaterCard',
          foreignKey: 'greaterCardId',
          set: function (Relation, card, greaterCard, originalSet) {
            greaterCard.lesserCardId = card.id;
            originalSet(lesserCard);
          }
        }
      ]
    }
  }
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-24
    • 1970-01-01
    • 2013-12-20
    • 2017-07-25
    相关资源
    最近更新 更多