我正在尝试使用Angularjs创建一个文件管理器,我最近发现了Breezejs并且有兴趣尝试使用它与我的后端进行通信并管理我的模型关系。后端是一个我可以完全控制的休息api。
然而,我遇到了一个问题。我知道文件的ID,所以我想请求backend_url/files/:fileId
形式的url,其中:fileId
是base64编码文件的url。根据文档,我应该使用EntityManager.fetchEntityByKey()
来实现此目的。这是我用来创建Angularjs服务的函数:
var FilestoreService = function () {
var dataService, manager;
dataService = new breeze.DataService({
serviceName: "../VFS-Symfony-Backend/web/app_dev.php/filesystems/local/",
hasServerMetadata: false
});
manager = new breeze.EntityManager({
dataService: dataService
});
manager.metadataStore.addEntityType(fileEntityType);
return {
findOneById: function (id) {
/* I have tried to leave the 3th argument empty or changing it to false with the same results */
return manager.fetchEntityByKey("File", id, true).then(function(){console.log("success");}).fail(function(){console.log("failure");});
/* I have also tried the following approach with the same result:
var type, key, query;
type = manager.metadataStore.getEntityType("File");
key = new breeze.EntityKey(type, id);
query = breeze.EntityQuery.fromEntityKey(key);
return manager.executeQuery(query);
*/
}
};
};
其中fileEntityType
定义为:
var FileEntityType = new breeze.EntityType({
shortName: "File"
});
FileEntityType.addProperty(new breeze.DataProperty({
name: "uri",
dataType: breeze.DataType.String,
isNullable: false
}));
FileEntityType.addProperty(new breeze.DataProperty({
name: "mTime",
dataType: breeze.DataType.Int16,
isNullable: false
}));
FileEntityType.addProperty(new breeze.DataProperty({
name: "type",
dataType: breeze.DataType.String,
isNullable: false
}));
FileEntityType.addProperty(new breeze.DataProperty({
name: "size",
dataType: breeze.DataType.int16,
isNullable: true
}));
然而,当我呼叫findOneById
时,没有向服务器发出请求,并且有2行被记录到控制台:
Should be empty:[]
来自q.js
failure
(根据fail()
回调函数)
“正常”查询(manager.executeQuery(new breeze.EntityQuery().from("Files"));
)确实会按预期向服务器发出请求。
我真的很迷失在这里。我整个周末都在寻找解决方案,并最终决定发布SO希望有人可以帮助我。
非常感谢阅读。
答案 0 :(得分:4)
至少有一个问题是您尚未确定"文件"的元数据描述中的密钥(' id'?)。实体类型。您已定义除' id'之外的所有其他属性属性。
你知道这一点,但是让我告诉其他读者这个问题谁可能不明白你是在JS客户端上定义元数据而不是从服务器上检索它。
我也很好奇你为什么要使用int16?这真的是正确的类型吗?你真的需要削减这两个字节吗?
最后,Breeze的fetchEntityByKey
不会以#34; backend_url / files /:fileId "的形式发出请求网址。相反,请求网址将是" backend_url / files /?id =:fileId "适合OData查询。请参阅DocCode示例的queryTests.cs中的Id查询的网络流量。
如果服务器需要您指定的URL,您仍然可以获取该文件。您不会使用Breeze查询语法。您只需使用其预期的URL点击服务,例如,
function findOne(id) { // check cache first var file = manager.getEntityByKey('File', id); if (file) { console.log("got it from cache"); return Q(file); // got it; return in resolved promise } // not in cache; get from server return breeze.EntityQuery .from('Files/'+id) // constructs the URL you want .using(manager).execute() .then(function(data){ console.log("success");} // return the file in a resolved promise return data.results[0] || null; }) .fail(function(error){ console.log("failure: "+ error.message); }); }
这是DocCode示例中queryTest.cs中getByIdCacheOrRemote
方法的变体。
是的,它的时间更长。您重新实现fetchEntityByKey
,以便按预期方式点击远程服务。
该方法首先在缓存中查找文件。 getEntityByKey
是缓存的同步搜索。 findOne
方法具有异步语法...返回一个promise ...因为可能必须转到服务器。因此,如果我们在缓存中找到该文件(同步),我们将结果包装在已解析的Q.js中,以使调用者受益,期望findOne
是异步的。
如果在缓存中找不到该文件,则使用"查询"进入服务器。 实际上只是您选择的网址上的请求。
我很久没试过了。我确定你会告诉我它是否有效......或者不是。如果它没有,它应该和我们一样修复它。
答案 1 :(得分:1)
当Ward建议我创建的EnityType确实需要将其中一个字段标记为关键字段。除此之外,EntityType还需要将defaultResourceName
提供给其构造函数。我认为这解释了为什么'普通'查询确实有效(resourceName由from()
提供)以及为什么fetchEntityByKey不起作用。更新后的FileEntityType现在如下所示:
var FileEntityType = new breeze.EntityType({
shortName: "File",
defaultResourceName: "files"
});
FileEntityType.addProperty(new breeze.DataProperty({
name: "id",
dataType: breeze.DataType.String,
isNullable: false,
isPartOfKey: true
}));
// These properties were not altered
FileEntityType.addProperty(new breeze.DataProperty({
name: "uri",
dataType: breeze.DataType.String,
isNullable: false
}));
FileEntityType.addProperty(new breeze.DataProperty({
name: "mTime",
dataType: breeze.DataType.Int16,
isNullable: false
}));
FileEntityType.addProperty(new breeze.DataProperty({
name: "type",
dataType: breeze.DataType.String,
isNullable: false
}));
FileEntityType.addProperty(new breeze.DataProperty({
name: "size",
dataType: breeze.DataType.int16,
isNullable: true
}));