Breeze 函数链陷阱





2.00/5 (1投票)
Breeze 陷阱。理解实体查询函数链的变化。
引言
Breeze,你用过吗?没有?那你应该了解一下。我不会说它是继切片面包以来最好的发明,因为它还不是(目前)。但如果你正在使用 oData/wcf 服务来支持 HTML5 Web 应用程序,你应该感兴趣。
我喜欢 Breeze,但仍然遇到一个问题,简单来说就是难以弄清楚。
问题
我不会解释 Breeze 是什么。因为如果你没有使用它,可以跳过阅读。但我遇到一个令人困惑的问题在使用 Breeze 时,这个问题很容易解释。如果你知道 Breeze 的函数链是如何工作的。
假设你有以下代码
var query=new breeze.entityQuery().from("Customers").expand("Orders");
manager.executeQuery(query).then( function(returndata) { ....
这是一个很棒的查询。它会向你的 oData Web 服务请求所有客户及其订单。它会创建类似 http://<webservice-endpoint>/Customers/?$expand=Orders 的内容。
在我的应用程序中,我遇到的问题是,我不能简单地请求扩展 Customers
的所有可能的关联属性。数量实在太多了。我决定必须编写一些包装函数,并根据用户所在位置决定要扩展哪些内容。最终,我想在 if then
语句中包装 Breeze 的扩展功能。
var query=new breeze.entityQuery().from("Customers");
if(someInputVar) {
query.expand("Orders");
}
令我惊讶的是,这并没有扩展订单。查看 http 流时,我没有看到 $expand=Orders
。
为什么没有?
现在我知道为什么了。我不同意开发者这样做的原因,但至少我知道了。如果你尝试进行正确的函数链,你很可能会从你的函数内部返回对象的实例。例如:
myfancyobject.prototype.doSomethingAwesome=function() {
this.doAwesome();
return this;
}
这样,你可以继续更改你的函数,并且可以根据需要中断链。例如,使用 if then else
。
Breeze 的构建者认为这会毫无意义。或者我没有理解这种设计的原因,因为我不够聪明。
他们决定函数链不应该返回 this,而是返回 this 的克隆。他们的返回值看起来像这样:
myfancyobject.prototype.doSomethingAwesome=function() {
this.doAwesome();
return clone(this);
}
所以当你执行 query.expand
时,你并没有更改查询对象。expand
函数会返回 entityQuery 的新实例。
我花了很长时间才发现这一点。当我发现时,我感到非常震惊。我仍然不理解这种设计背后的原因,但我可以轻松修复我的错误查询!!!
var query=new breeze.entityQuery().from("Customers");
if(someInputVar) {
//reassign query!!
query=query.expand("Orders");
}
只需使用返回的克隆重新分配查询变量!
我不得不阅读 Breeze 本身的源代码才能找到解决这个简单问题的办法。我在这里分享它,因为如果你遇到它,很难弄清楚。
历史
- 2014-5-24:创建提示