5

当我的应用程序加载时,我注册了一个过滤器和一个带有角度的服务。但是过滤器试图在服务返回数据之前执行,所以我的项目集合在过滤器中咆哮。我有一个小提琴,但我不知道你是否可以在小提琴中使用 $http,因为它是一个外部资源。这是我的小提琴 抱歉,它实际上不起作用。它经历了很多。我认为我的问题是时机。我需要过滤器来等待 http 响应,或者只是不“强制”本身。

我现在得到的错误是“项目未定义”,因为这是应用过滤器的地方。在我尝试将 http 调用混入服务之前,我确实有这个工作。但我觉得这是有角度的方式,我“只是想遵守”。

当我的控制器触发时,它会调用获取数据:

eventApi.async().then(function () {
    $scope.eventCollection = eventApi.data();
});

但在它回来之前,过滤器应用在 html 中:

 <tr ng:repeat="event in events  | myEventFilter:ddlFilter |
       orderBy:sort.column:sort.descending">

小提琴

4

1 回答 1

8

这是您更新的小提琴的一个分支,它修复了几个缺失的依赖项(eventApi未注入控制器,$timeout未注入eventApi服务)。我的评论将基于此代码:http: //jsfiddle.net/BinaryMuse/zww7e/1/

这个小提琴成功地让我们解决了您发布的问题:“无法读取未定义的属性'长度'”在您的过滤器中。一般来说,过滤器应该能够默认处理空值/未定义值。我只需修改过滤器以读取如下内容:

return function (items, eventFilterType) {
  var arrayToReturn = [];
  if (items === undefined) return arrayToReturn;
  // ...
}

那应该解决您的根本问题;小提琴现在运行没有错误,尽管它似乎不能正常工作;据我所知,这是因为您正在设置$scope.eventCollection而不是$scope.eventsif (live)控制器的部分中。进行此更改会导致数据实际显示在视图中。

但是,您可能对 Angular 的另一个属性感兴趣:当您使用用 构建的 Promise 时$q,您可以将视图直接绑定到该 Promise,并且该视图会将视为您将其绑定到该Promise 的已解析值。因此,例如,您可以执行以下操作:

// in the service
$timeout(function () {
  deffered.resolve(fakeEvents); // <-- resolve with the data
}, 2000);
return deffered.promise;

// in the controller
if (live) {
  $scope.events = eventApi.async();
}

这是演示此技术的小提琴的更新版本:http: //jsfiddle.net/BinaryMuse/zww7e/2/

[更新]

正如 Jeff 在评论中指出的那样,Angular 正在弃用自动承诺展开;你可以在这里看到提交,但这里是消息:

fix($parse): 弃用 promise unwrapping 并使其成为可选

此提交禁用承诺展开并添加 $parseProvider.unwrapPromises() getter/setter api,允许开发人员在需要时重新打开该功能。Promise unwrapping 支持将在未来从 Angular 中移除,并且此设置仅允许在过渡期间启用它。

如果启用了展开,Angular 将记录一个关于展开承诺的每个表达式的警告(为了减少噪音,每个表达式只记录一次)。要禁用此日志记录,请使用 $parseProvider.logPromiseWarnings(false).

以前在表达式求值期间在表达式中的任何位置找到的承诺在未解决时将评估为未定义,如果已实现则评估为履行值。

这是一个没有被证明非常有用或流行的功能,主要是因为模板中的数据访问(作为原始值访问)和控制器代码(作为承诺访问)之间的二分法。

在大多数代码中,我们最终在控制器中手动解析 Promise,或者通过路由自动解析并以这种方式统一模型访问。

自动承诺解包的其他缺点:

  • 在构建组件时,通常希望收到原始承诺
  • 增加了复杂性并减慢了表达式评估
  • 由于需要生成的代码量很大,使得表达式代码预生成没有吸引力
  • 使 IDE 自动完成和工具支持变得困难
  • 增加了太多的魔法

重大变化: $parse 和模板一般将不再自动解包承诺。此功能已被弃用,如果绝对需要,可以在过渡期间通过 $parseProvider.unwrapPromises(true)api 重新启用它。

于 2013-02-01T22:46:50.190 回答