asp.net-web-api – ember-data:根据需要加载hasMany关联
|
(更新为ember-data API Rev 11 …) TL; DR 什么是使用DS.Adapter.findAssociation(…)DS.Adapter.findHasMany(…)正确的方式来加载hasMany关联按需?特别是,一旦加载子记录,您如何处理从服务器重新加载父记录清空hasMany数组的事实?我不想(也许不能)将父记录中的子记录的id包含在数组中。还是有另一种方法来做到这一点我失踪了? 作为附注,我感到困惑的是在一个hasMany / belongsTo定义中应该传递什么选项来进行关键连接(如果我没有加载数据或ids数组,我应该使用映射),所以如果你认为我的问题可能在于我的关联定义,很有可能你是对的。 长版 我正在编写自己的DS.RESTAdapter子类,将ember数据与ASP.NET WebAPI后端(使用实体框架)相结合。到目前为止这么好,但是我有一段时间让协会正常工作。 与this poster类似,我注意到,ember数据的首页表示曾经说过,如果您的模型中有一个hasMany关联,并且获得该属性,那么该商店将发出对该子记录的请求。从页面引用:
这意味着,如果您不负载并且不包括ids数组,会发生什么。我意识到这些文档有些过时,但是我无法在API版本7或更新版本9中发生这种情况。但是在版本9中,我找到了findAssociation方法,在版本11中有findHasMany方法,我猜这是可能已经被用来做这个事情,我正在试图使用。 为什么不包括ids或sideload的数组? 三个主要原因我不想这样做(可能不能): > ASP.NET WebAPI中的任何一项都不明显,至少没有使用简单的基于装饰的方法。而且,我真的很喜欢后端的简单性和薄度,EF和WebAPI几乎完全是每个实体的样板,我已经完成了!我甚至得到OData过滤支持“免费”。 试图使用findAssociationfindHasMany 我已经在API版本9(和一些较早的版本,但不是全部?)11中,我可以实现DS.Adapter.findAssociation DS.Adapter.findHasMany方法来检索hasMany关联的子记录。这主要是工作,但需要一些体操。这是我的广义findAssociation findHasMany方法: findHasMany: function (store,record,relationship,ids) {
var adapter = this;
var root = this.rootForType(relationship.type);
var query = relationship.options.query(record);
var hits = store.findQuery(relationship.type,query);
hits.on('didLoad',function () {
// NOTE: This MUST happen in the callback,because findHasMany is in
// the execution path for record.get(relationship.key)!!! Otherwise causes
// infinite loop!!!
var arrMany = record.get(relationship.key);
if (hits.get('isLoaded')) {
arrMany.loadingRecordsCount = 1 + hits.get('length') + (typeof arrMany.loadingRecordsCount == "number" ? arrMany.loadingRecordsCount : 0);
hits.forEach(function (item,index,enumerable) {
arrMany.addToContent(item);
arrMany.loadedRecord();
});
arrMany.loadedRecord(); // weird,but this and the "1 +" above make sure isLoaded/didLoad fires even if there were zero results.
}
});
}
为了使这个工作,我的许多定义设置了一个查询选项值,它是一个记录上的函数,该函数返回对该请求中的查询字符串的参数的哈希值。由于这是一个ASP.NET WebAPI后端,这可能是一个OData过滤器,例如: App.ParentEntity = DS.Model.extend({
...
children: DS.hasMany('App.ChildEntity',{
query: function (record) {
return {
"$filter": "ChildForeignKey eq '" + record.get('id') + "'"
};
}
})
});
其中一个技巧是使用addToContent(item)将项目添加到ManyArray中,以便父记录不会像编辑一样被标记为“脏”。另一个是,当我最初检索父记录的JSON时,我必须为关联名称的键手动设置一个true值(来自服务器的JSON根本没有密钥)。即: var a = Ember.isArray(json) ? json : [json];
for (var i = 0; i < a.length; i++) {
type.eachAssociation(function (key) {
var meta = type.metaForProperty(key);
a[i][key] = true;
});
}
这听起来很棒,但是这就是为什么:如果你看看DS.Store.findMany的实现,并找到findAssociation findHasMany在哪里被调用的位置,你会发现: findMany: function(type,ids,relationship){
...
if (!Ember.isArray(ids)) {
var adapter = this.adapterForType(type);
if (adapter && adapter.findHasMany) { adapter.findHasMany(this,ids); }
else { throw fmt("Adapter is either null or does not implement `findMany` method",this); }
return this.createManyArray(type,Ember.A());
}
如果您从ember-data内部函数hasAssociation hasRelationship中查找findMany的这一行,您将看到第二个参数传递的内容: relationship = store.findMany(type,ids || [],this,meta); 所以,找到FindAsHouseMany被调用的唯一方法是使JSON中的值是“真实的”,但不是一个数组 – 我使用true。我认为这是一个错误/不完整,或者表明我在错误的轨道上 – 如果有人能告诉我哪个也是伟大的。 有了这些,我可以得到余烬数据自动向服务器发出一个请求给子记录,例如到http://myserver.net/api/child_entity/$filter=ChildForeignKey eq’42’,它的工作原理 – 子记录被加载,并且它们与父记录相关联(顺便说一下,inverse belongsTo关系被正确地填充尽管事实上我并没有明确地触及它 – 我不知道在哪里或发生了什么。 但如果我不停在那里,那很快就会崩溃。 处理重新加载父记录 所以说我成功地将子记录加载到父记录中,然后导航到检索所有父记录的位置(以填充菜单)。由于新加载的父记录没有ids的数组,没有任何东西被加载,所以父记录不再有任何孩子被刷新!更糟糕的是,ManyArray的Lloaded属性依然是真实的!所以我甚至不能观察任何东西来重新加载孩子们。 所以如果我同时有一个屏幕上的显示子值的视图,它会立即变为没有子记录值。或者如果我导航回到一个,当App.store.find(‘App.ParentEntity’,42)被调用时,记录从商店加载而不需要服务器,当然它没有子记录。 这是提示#2,我可能会这样做错了。那么…根据需要装载子记录的正确方法是什么? 非常感谢! 解决方法根据最新的Ember Data(截至2013年1月25日)…这里我的解决方案是延迟加载有很多关系。我修改了DS.hasMany,并向DS.Adapter添加了一个方法。我在DS.hasMany中改了两行: DS.hasMany = function(type,options) {
Ember.assert("The type passed to DS.hasMany must be defined",!!type);
return (function(type,options) {
options = options || {};
var meta = { type: type,isRelationship: true,options: options,kind: 'hasMany' };
return Ember.computed(function(key,value) {
var data = get(this,'data').hasMany,store = get(this,'store'),relationship;
if (typeof type === 'string') {
type = get(this,type,false) || get(Ember.lookup,type);
}
meta.key = key;
ids = data[key];
relationship = store.findMany(type,meta);
set(relationship,'owner',this);
set(relationship,'name',key);
return relationship;
}).property().meta(meta);
})(type,options);
};
首先,我添加了元对象的关键字… meta.key = key; …其次,如上所述,我通过更改…从findMany调用中删除了空数组 relationship = store.findMany(type,meta); …至… relationship = store.findMany(type,meta); …允许ids被传递到findMany作为未定义。 接下来,我添加了一个didFindHasMany钩子到DS.Adapter: DS.Adapter.reopen({
/**
Loads the response to a request for records by findHasMany.
Your adapter should call this method from its `findHasMany`
method with the response from the backend.
@param {DS.Store} store
@param {subclass of DS.Model} type
@param {any} payload
@param {subclass of DS.Model} record the record of which the relationship is a member (parent record)
@param {String} key the property name of the relationship on the parent record
*/
didFindHasMany: function(store,payload,key) {
var loader = DS.loaderFor(store);
loader.populateArray = function(references) {
store.loadHasMany(record,key,references.map(function(reference) { return reference.id; }));
};
get(this,'serializer').extractMany(loader,type);
}
});
(编辑:安卓应用网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- asp.net-mvc-3 – 如何修改MVC3视图页面中的body类
- .net core azure部署失败:项目文件不存在
- asp.net-mvc-4 – 在MVC 4中创建下拉列表的最佳方法是什么?
- asp.net – bing地图花钱?
- asp.net-mvc – 测量时间调用ASP.NET MVC控制器操作
- asp.net-mvc – MVC / Unity – 如何将依赖项注入自定义Fil
- asp.net-mvc – 捕获文件名作为参数的MVC路由
- asp.net-mvc – Razor MVC4 Url.Action无效
- asp.net – 当我按浏览器BACK按钮会发生什么?
- asp.net – 以纯文本识别URL
- asp.net – PayPal Express Checkout MVC C#示例
- asp.net – Internet Explorer 9中的URL查询字符
- asp.net-mvc – ASP.NET MVC Route,在控制器之前
- 将用户添加到角色ASP.NET身份
- 最佳实践:ASP.NET中的CSS或主题?
- asp.net-mvc-3 – 将我的MVC 3应用程序迁移到MVC
- 学习:正则表达式的基本语法
- 对asp.net网站进行基准测试,我可以使用jmeter吗?
- asp.net – 如何禁用提交行为的asp:ImageButton
- asp.net-core – 在ASP.NET Core中将html导出为p
