从$scope调用时未激发角度资源调用$看



我创建了一个指令,用于监视day属性,并在属性值更改时检索远程资源。CoffeeScript代码:

angular.module('app.directives').directive 'myDirective', ['$timeout', ($timeout)->
    DirectiveController=($scope, activityResource)->
        # Load activities
        load= ()->
            activityResource.get {
                day: $scope.day
                environment_id: $scope.environment.id
            },
            (data)->
                $scope.activities = data.activities
        # Watch environment and reload activities
        $scope.$watch 'environment', (value) ->
            load()
        # Watch selected day to reload activities
        $scope.$watch 'day', (value) ->
            load()
...
]

每次day更改时都会调用load方法,但结果回调从未触发。网络检查显示该请求未发送到远程端。我找到的唯一解决方法是推迟使用$timeout服务执行load方法:

        $scope.$watch 'day', (value) ->
            $timeout (()-> load()), 10

我怀疑有一个问题与作用域生命周期有关,但我不明白为什么必须推迟对资源的调用。

更新

资源源代码:

resources = angular.module('app.resources', ['ngResource'])
...
resources.factory 'app.activityResource', ['$resource', 'app.endpoint', ($resource, endpoint)->
  $resource "#{endpoint()}/user/environments/:environment_id/activities/:id/:verb",
  {environment_id: "@environment_id", id: "@id"},
  latest:
    method : 'GET'
    params:
      verb: 'latest'
  annual:
    method : 'GET'
    params:
      verb: 'annual'
]

我还在代码摘录中添加了第二个关注属性(environment),用作查询资源的参数。

更新2

我不知道它是否相关,但我们正在使用CORS访问远程端(这似乎很好)。

您没有看到请求被触发的原因是,作为$http调用的一部分,配置会作为承诺传递给每个拦截器。

https://github.com/angular/angular.js/blob/b99d064b6ddbcc9f59ea45004279833e9ea82928/src/ng/http.js#L665-L670

在angular中,$q承诺只在$digest周期开始时得到解决。因此,在$digest循环发生之前,您的HTTP请求甚至不会被触发,这就是为什么您看到将$timeout包装在它周围会有所帮助(超时会导致$digest)。

https://github.com/angular/angular.js/blob/2a5c3555829da51f55abd810a828c73b420316d3/src/ng/q.js#L160https://github.com/angular/angular.js/blob/3967f5f7d6c8aa7b41a5352b12f457e2fbaa251a/src/ng/rootScope.js#L503-L516

您还可以通过重新创建您看到的错误条件并监视网络请求来验证这一点。在你运行这个之后,你应该会看到你的请求被触发:

angular.element( "[ng-app]" ).scope().$digest()

该代码在$rootScope上引发$digest循环,导致未解决的承诺得到解决。

请参阅此问题进行更多讨论,因为我同意这是一种令人惊讶的行为。

https://github.com/angular/angular.js/issues/2881

最新更新