Ember:创建模型的 DS.belongsTo *外部*
Ember: create a DS.belongsTo *outside* of a Model
我想在我自己的 class 中理想地创建一个 DS.belongsTo
/ BelongsToRelationship
(这是一个 Ember.Object
,但不是 DS.Model
),或者重新创建功能,让我在自己的 class 中保留对记录的引用。我不知道是否可以在 DS.Model
之外使用 DS.belongsTo
,或者如果可以,如何设置它。
背景:
我有一个使用 ember-data + ember-fire + firebase 的 ember-cli 应用程序。我的一个模型有一个属性,它是一个保存“类型特定”信息的对象。我根据它描述的 type 将这个对象转换为我自己的 class ,有时该类型会引用数据库中的其他记录。在这些情况下,我想在我的 typeSpecific class 中设置一个 DS.belongsTo
属性,我可以 link 以与 linking 中的关系相同的方式常规型号。
选择:
经过大量搜索,但没有找到任何有关如何执行此操作的信息,我自己制作了 class,这让我完成了大部分工作。我刚刚注意到,虽然我可以更改它在客户端引用的记录并更新它,但如果我在服务器端更改它,我就不会收到更新,所以它又回到了绘图板。
如果有人能告诉我如何使这种替代方法起作用也能达到目的。这个 class 的想法是我将模型名称和 ID 传递给它,它应该创建模型引用,然后在任何一方发生变化时保持 model
和 id
同步,并且如果连接到的模型上的任何内容发生更改,就像常规关系一样,则通过更新。
export default Ember.Object.extend({
id: null,
table: undefined,
model: undefined,
store: undefined,
init: function() {
this._super();
if(this.id && !this.model) {
this.updateModel();
}
else if(this.model && !this.id) {
this.updateId();
}
},
updateModel: function() {
var self = this;
if( this.get('id') ) {
this.store.find(this.get('table'), this.get('id')).then( function(model) {
self.set('model', model);
});
}
else {
self.set('model', undefined);
}
}.observes('id','table'),
updateId: function() {
if(this.get('model')) {
this.set('id', this.get('model.id'));
}
else {
this.set('id', null);
}
}.observes('model'),
});
编辑:操作上面对象的代码:
//Creating a reference:
this.set('target', ModelPointer.create({store:this.get('store'), table:this.get('targetTable'), id:targetId}));
//or:
this.set('target', ModelPointer.create({store:store, table:'myTable'}));
...
this.set('target.id', '42');
我相信目前如果我在客户端上更改 id
或 model
,另一个会自动更新,例如:
//either:
this.set('target.id', '43');
//or:
this.store.find('myTable','43').then( function(newModel) {
self.set('target.model', newModel);
});
问题是,如果我登录 Firebase 并更改 myTable['42'].name='Fred'
,那么我网页上显示的 link 编辑为 target.model.name
的值不会更新为 'Fred'。我怀疑如果我在客户端将 target.model.name
设置为 'Fred' 并保存它也不会更新服务器上的值(?)
我想出的最干净的解决方案是不单独存储 id
(留给模型本身)。我已经验证我在 Firebase 中所做的更改会很好地传播到显示的条目。
通过此解决方案设置,可以使用其 id
或简单地使用模型实例本身来完成引用模型。有关示例,请参阅控制器代码。
首先提供一些Firebase的测试数据供参考:
{
"testModels": {
"1": {
"name": "Model one"
},
"2": {
"name": "The second model"
},
"3": {
"name": "Third is the charm"
}
}
}
因此它的模型 app/models/test-model.js
只需要其中的名称。
这是我的 belongsTo
类代理 class,我把我的放在 app/utils/proxy-class.js
下,但它应该是一个 Mixin:
import Ember from 'ember';
export default Ember.Object.extend({
remote: null, // reference to the remote DS.Model
store: null, // reference to the actual store
storeModel: null, // name of the model in the store
_watchRemote: function() {
var self = this;
if ( typeof self.get('remote') === 'object' ) {
// do nothing, already an object
if ( ! Ember.isPresent( self.get('store') ) ) {
// but set the store from the model
self.set( 'store', self.get('remote.store') );
}
} else if ( typeof self.get('remote') === 'string' ||
typeof self.get('remote') === 'number' ) {
// it's an id, so fetch the model
self._fetchModel( self.get('remote') );
}
}.observes('remote').on('init'), // on change, and during object init
_fetchModel: function( id ) {
var self = this;
self.store.find( self.get('storeModel'), id ).then(
function( model ) {
self.set( 'remote', model );
}, function ( err ) {
console.error( "couldn't read from the store:", err );
});
},
});
我创建了这个控制器,并使用浏览器控制台即时更改模型以测试模型更改是否被提取:
import Ember from 'ember';
import proxyClass from '../utils/proxy-class';
export default Ember.Controller.extend({
model: {
remoteFromId: null,
remoteFromModel: null,
},
init: function() {
var self = this;
self.set( 'model.remoteFromId',
proxyClass.create({
remote: 1,
store: self.get('store'),
storeModel: 'test-model',
})
);
self.get('store').find( 'test-model', 2 )
.then( function( model ) {
self.set( 'model.remoteFromModel',
proxyClass.create({
remote: model,
storeModel: 'test-model',
// no store provided here: set from the model
})
);
});
}
});
控制器模板:
<p>remoteFromId: {{model.remoteFromId.remote.id}}
{{model.remoteFromId.remote.name}}</p>
<p>remoteFromModel: {{model.remoteFromModel.remote.id}}
{{model.remoteFromModel.remote.name}}</p>
我想在我自己的 class 中理想地创建一个 DS.belongsTo
/ BelongsToRelationship
(这是一个 Ember.Object
,但不是 DS.Model
),或者重新创建功能,让我在自己的 class 中保留对记录的引用。我不知道是否可以在 DS.Model
之外使用 DS.belongsTo
,或者如果可以,如何设置它。
背景:
我有一个使用 ember-data + ember-fire + firebase 的 ember-cli 应用程序。我的一个模型有一个属性,它是一个保存“类型特定”信息的对象。我根据它描述的 type 将这个对象转换为我自己的 class ,有时该类型会引用数据库中的其他记录。在这些情况下,我想在我的 typeSpecific class 中设置一个 DS.belongsTo
属性,我可以 link 以与 linking 中的关系相同的方式常规型号。
选择:
经过大量搜索,但没有找到任何有关如何执行此操作的信息,我自己制作了 class,这让我完成了大部分工作。我刚刚注意到,虽然我可以更改它在客户端引用的记录并更新它,但如果我在服务器端更改它,我就不会收到更新,所以它又回到了绘图板。
如果有人能告诉我如何使这种替代方法起作用也能达到目的。这个 class 的想法是我将模型名称和 ID 传递给它,它应该创建模型引用,然后在任何一方发生变化时保持 model
和 id
同步,并且如果连接到的模型上的任何内容发生更改,就像常规关系一样,则通过更新。
export default Ember.Object.extend({
id: null,
table: undefined,
model: undefined,
store: undefined,
init: function() {
this._super();
if(this.id && !this.model) {
this.updateModel();
}
else if(this.model && !this.id) {
this.updateId();
}
},
updateModel: function() {
var self = this;
if( this.get('id') ) {
this.store.find(this.get('table'), this.get('id')).then( function(model) {
self.set('model', model);
});
}
else {
self.set('model', undefined);
}
}.observes('id','table'),
updateId: function() {
if(this.get('model')) {
this.set('id', this.get('model.id'));
}
else {
this.set('id', null);
}
}.observes('model'),
});
编辑:操作上面对象的代码:
//Creating a reference:
this.set('target', ModelPointer.create({store:this.get('store'), table:this.get('targetTable'), id:targetId}));
//or:
this.set('target', ModelPointer.create({store:store, table:'myTable'}));
...
this.set('target.id', '42');
我相信目前如果我在客户端上更改 id
或 model
,另一个会自动更新,例如:
//either:
this.set('target.id', '43');
//or:
this.store.find('myTable','43').then( function(newModel) {
self.set('target.model', newModel);
});
问题是,如果我登录 Firebase 并更改 myTable['42'].name='Fred'
,那么我网页上显示的 link 编辑为 target.model.name
的值不会更新为 'Fred'。我怀疑如果我在客户端将 target.model.name
设置为 'Fred' 并保存它也不会更新服务器上的值(?)
我想出的最干净的解决方案是不单独存储 id
(留给模型本身)。我已经验证我在 Firebase 中所做的更改会很好地传播到显示的条目。
通过此解决方案设置,可以使用其 id
或简单地使用模型实例本身来完成引用模型。有关示例,请参阅控制器代码。
首先提供一些Firebase的测试数据供参考:
{
"testModels": {
"1": {
"name": "Model one"
},
"2": {
"name": "The second model"
},
"3": {
"name": "Third is the charm"
}
}
}
因此它的模型 app/models/test-model.js
只需要其中的名称。
这是我的 belongsTo
类代理 class,我把我的放在 app/utils/proxy-class.js
下,但它应该是一个 Mixin:
import Ember from 'ember';
export default Ember.Object.extend({
remote: null, // reference to the remote DS.Model
store: null, // reference to the actual store
storeModel: null, // name of the model in the store
_watchRemote: function() {
var self = this;
if ( typeof self.get('remote') === 'object' ) {
// do nothing, already an object
if ( ! Ember.isPresent( self.get('store') ) ) {
// but set the store from the model
self.set( 'store', self.get('remote.store') );
}
} else if ( typeof self.get('remote') === 'string' ||
typeof self.get('remote') === 'number' ) {
// it's an id, so fetch the model
self._fetchModel( self.get('remote') );
}
}.observes('remote').on('init'), // on change, and during object init
_fetchModel: function( id ) {
var self = this;
self.store.find( self.get('storeModel'), id ).then(
function( model ) {
self.set( 'remote', model );
}, function ( err ) {
console.error( "couldn't read from the store:", err );
});
},
});
我创建了这个控制器,并使用浏览器控制台即时更改模型以测试模型更改是否被提取:
import Ember from 'ember';
import proxyClass from '../utils/proxy-class';
export default Ember.Controller.extend({
model: {
remoteFromId: null,
remoteFromModel: null,
},
init: function() {
var self = this;
self.set( 'model.remoteFromId',
proxyClass.create({
remote: 1,
store: self.get('store'),
storeModel: 'test-model',
})
);
self.get('store').find( 'test-model', 2 )
.then( function( model ) {
self.set( 'model.remoteFromModel',
proxyClass.create({
remote: model,
storeModel: 'test-model',
// no store provided here: set from the model
})
);
});
}
});
控制器模板:
<p>remoteFromId: {{model.remoteFromId.remote.id}}
{{model.remoteFromId.remote.name}}</p>
<p>remoteFromModel: {{model.remoteFromModel.remote.id}}
{{model.remoteFromModel.remote.name}}</p>