65.9K
CodeProject 正在变化。 阅读更多。
Home

Breeze 函数链陷阱

starIconstarIconemptyStarIconemptyStarIconemptyStarIcon

2.00/5 (1投票)

2014年5月24日

CPOL

2分钟阅读

viewsIcon

10821

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:创建提示
© . All rights reserved.