我正在开发一个小型博客引擎,用户可以在其中创建博客条目并可以将标签链接到条目。它是多对多关系,但由于 Breeze 还无法管理这种关系,我必须将联接表暴露给 Breeze ,以便我可以逐步保存数据。我的问题就在这里。
表格:
- 博客条目
- 博客条目标签
- 标签
场景:
- 用户打开“新博客条目”表单或选择要编辑的现有博客
- 输入文本等
- 选择一个或多个标签
业务逻辑:
- 通过 Breeze 创建一个新实体/查询所选实体
- 保存博客条目(第一个服务器调用,如果博客条目是新条目,则返回 blog_id)
- 检查标签和博客条目之间已存在的连接,如果博客条目被编辑,则现有的 blogEntry-标签关系可能会发生变化(第二次服务器调用)
- 根据标签名称从标签表中选择 tag_id(第三次服务器调用)
- 通过 Breeze 创建 BlogEntrytag 实体
- 将 BlogEntrytag 实体保存到数据库中(第四次服务器调用)
我认为顺序必须是连续的。
我有这段代码,正如您所看到的附加屏幕截图,由“_blogEntryEnttity”标记的控制台日志记录不会等到数据从服务器返回,并且它将在由“_blogEntryEnttity inside”标记的控制台日志记录之前执行。当代码稍后尝试设置 title 属性时,将引发引用异常。
var blogEntryEntityQueryPromise = datacontext.blogentry.getById(_blogsObject.id);
blogEntryEntityQueryPromise.then(function (result)
{
console.log('result', result);
_blogEntryEntity = result[0];
console.log('_blogEntryEnttity inside', _blogEntryEntity);
//if I need synchronous execution then I have to put the code here which must be executed consecutively
});
console.log('_blogEntryEnttity', _blogEntryEntity);
}
//mapping the values we got
_blogEntryEntity.title = _blogsObject.title;
_blogEntryEntity.leadWithMarkup = _blogsObject.leadWithMarkup;
_blogEntryEntity.leadWithoutMarkup = _blogsObject.leadWithoutMarkup;
_blogEntryEntity.bodyWithMarkup = _blogsObject.bodyWithMarkup;
_blogEntryEntity.bodyWithoutMarkup = _blogsObject.bodyWithoutMarkup;
console.log('_blogEntryEnttity', _blogEntryEntity);
示例来自here .
我的问题是,为什么不等到数据返回呢?遇到这样的情况,该如何处理呢?
但是,我发现,如果我需要同步执行,那么我应该将代码放入从 Promise 检索数据之后的 success 方法中。然而,我真的不喜欢这个解决方案,因为我的代码在一段时间后会变得很难看并且难以维护。
datacontext.blogentry.getById 如下所示,实现在抽象类中,您也可以找到下面的代码。整个存储库模式来自 John Papa 的 course在 Pluralsight 上。
存储库类方法
function getById(id)
{
return this._getById(this.entityName, id);
}
抽象存储库类方法。根据Breeze's documentation page EntityQuery 类的执行方法返回一个 Promise。
function _getById(resource, id) {
var self = this;
var manager = self.newManager;
var Predicate = breeze.Predicate;
var p1 = new Predicate('id', '==', id);
return EntityQuery.from(resource)
.where(p1)
.using(manager).execute()
.then(success).catch(_queryFailed);
function success(data) {
return data.results;
}
}
非常感谢您的帮助!
最佳答案
我认为您不需要所有这些往返。我会这样做:
查询所有可用的标签实体,以便它们位于 EntityManager 的缓存中(无论如何,您都需要它们来填充 UI)。
如果是现有的BlogEntry,则只需查询该BlogEntry及其所有关联的BlogEntryTag实体即可; Breeze 会将 BlogEntryTags 连接到缓存中与其关联的标签。如果用户选择/取消选择 BlogEntry 的标签,您将添加/删除 BlogEntryTags。
var query = EntityQuery.from("BlogEntries").where("id", "==", id).expand("BlogEntryTags");
如果它是一个新的 BlogEntry,则它不会有任何 BlogEntryTags。在用户选择一些标签后,您将在保存时创建这些标签。
通过一次
saveChanges
调用将添加/更新的 BlogEntry 和任何添加/删除的 BlogEntryTag 实体保存到数据库。
请参阅Presenting Many-to-Many doc 及其 associated plunker进行更深入的研究。 UI 与您想要的不同,但底层概念很有用。
关于javascript - 等待数据返回,与 Angular 和 Breeze 同步调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29808749/