更新 js-data 关系对象的正确方法
Proper way of updating js-data relation objects
我有一个相同类型对象的链表:
获取/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();
我在没有 js-data 的情况下实现了这一点,像这样自定义 setter:
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 关系 属性 setters 的方法。我可以使用 cardService.setGreaterCard(card, greaterCard);
之类的方法创建一个单独的服务来更新列表结构,但这不会那么方便。 属性 更改时是否有更好的更新链接对象的方法?
js数据版本:2.9.0
在 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);
}
}
]
}
}
});
我有一个相同类型对象的链表:
获取/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();
我在没有 js-data 的情况下实现了这一点,像这样自定义 setter:
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 关系 属性 setters 的方法。我可以使用 cardService.setGreaterCard(card, greaterCard);
之类的方法创建一个单独的服务来更新列表结构,但这不会那么方便。 属性 更改时是否有更好的更新链接对象的方法?
js数据版本:2.9.0
在 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);
}
}
]
}
}
});