调用 $scope 函数的自定义指令导致 $rootScope:infdig

Posted

技术标签:

【中文标题】调用 $scope 函数的自定义指令导致 $rootScope:infdig【英文标题】:Custom Directive calling $scope function causes $rootScope:infdig 【发布时间】:2016-01-11 04:18:19 【问题描述】:

我曾尝试在此处查看其他 $rootScope:infdig 问题,但找不到一个能很好地向我解释或我理解的问题。与 AngularJs 文档相同。我希望有人可以提供帮助。

我在 $scope 上创建了一个函数,它接受一个参数并调用一个 api GET 请求并返回一个带有“id”和“name”的 json 对象。然后,此函数将对象的名称返回给调用它的指令。

该函数从指令中调用,但一旦调用,它就会陷入每秒一百个“rootScope:infdig”的错误。该指令也从不呈现返回的“名称”的文本。我知道 http 调用有效,因为我在控制台中记录了“名称”。

Error Screen

这是我的控制器:

owlyfm.controller('landingPageController', [ "$scope", "$log", "$http", "$location", "apiUrlsService", function ($scope, $log, $http, $location, apiUrlsService) 

 $http.get("https://api.backand.com:443/1/objects/Albums?pageSize=3&pageNumber=1&deep=true&relatedObjects=true")
    .success( function(result)
        $scope.featuredAlbums = result.data;
        //$log.info($scope.featuredAlbums);
    )
    .error( function(data, status)
        $log.error(data);
    );

    $scope.getAlbumArtist = function(artistId)

      $http.get("https://api.backand.com:443/1/objects/Artists/" + artistId)
        .success(function(result)
          var artistsName = result.name;
          $log.info(artistsName);
          return artistsName;
        );
    
]);

这里是我创建指令的地方:

owlyfm.directive("featuredAlbum", function()

return
    restrict: 'E',
    templateUrl: 'directives/featuredAlbum.html',
    scope: 
        albumObject: "=",
        getAlbumArtistFunction: "&"
    
  
);

这是我在视图中调用指令的地方

<div class="row fluid-container" >
    <featured-album ng-repeat="featuredAlbum in featuredAlbums" album-object="featuredAlbum" get-album-artist-function="getAlbumArtist(album)" class="col-md-4" ></featured-album>
</div>

这是指令本身:

    <div class="featuedAlbum">

        <div>
            <img class="img-responsive" ng-src=" albumObject.albumArtUrl "/>
        </div>

        <h4> albumObject.name </h4>
        <h5> getAlbumArtistFunction(  album: albumObject.Artists  ) </h5>
        <h6> albumObject.releaseDate </h6>

    </div>

我在做什么

总结一下,我正在做的是调用 api 来获取专辑对象,(我正在使用“Backand”顺便说一句)一旦我得到这个专辑对象,我就会用数据渲染 &lt;img&gt;&lt;h&gt; 标签我收到。这工作正常。

专辑对象具有 ID、名称、日期、imgUrl 和“艺术家”(这只是艺术家的 id)。然后,我使用这个“艺术家”ID 再次调用以获取与其关联的实际艺术家对象。这就是问题出现的地方。

问题

导致错误循环的是艺术家对象的 http 调用。即使我可以在日志中看到它正在获取艺术家的 json 对象,它也不会将其发送到指令。

我研究过的内容

我已阅读到将 ng-repeat 与指令中的函数一起使用时存在问题。但是,我并不完全理解它为什么以及如何应用在这里,也不知道如何改变它来实现我想要实现的目标。这里的所有其他问题都超出了我的想象。

如果有人能帮助我,将不胜感激。

【问题讨论】:

忘掉 Angular 1,Angular 2 即将推出,现在是测试版! 我的建议是,不要在视图调用的函数中发出任何 http 请求:它会被调用数百次。而且我认为无限摘要问题应该在那之后消失。 这似乎是一种竞争条件。 $http 是异步的并返回一个承诺。您正在遍历数组,并为数组中的每一行发出$http 调用;返回的每个调用都将启动一个 $digest 循环,然后该循环将重新遍历数组并重新启动 $http 调用,从而有效地无限循环您的代码。 可能可以通过在ng-repeat 上使用track by 子句,通过使用一次性绑定:: ::getAlbumArtistFunction 语法来解决此问题,或两者。但是,像这样连续调用这么多$http 是一个性能瓶颈,您最好在服务器上设计一个特定的端点,可以在一次调用中返回组合信息。 感谢各位的帮助。 @Haocheng 感谢您的意见,您建议我如何进行此调用以在视图中呈现数据? 【参考方案1】:

正如 cmets 中所说,调用将从视图内部的服务器获取数据的函数不是一个好主意, 因为它会调用多次,而你只需要调用一次。

您可以添加将在“featuredAlbum”构造函数中设置的“artistName”属性。

owlyfm.controller('featuredAlbumController', [ "$scope","$http",function ($scope, $http) $http.get("@987654321@" + $scope.artistId) .success(function(result) $scope.artistName = result.name; ); ]);

因此,$http 只会在控制器第一次运行时被调用一次。

【讨论】:

以上是关于调用 $scope 函数的自定义指令导致 $rootScope:infdig的主要内容,如果未能解决你的问题,请参考以下文章

AngularJS指令$ scope未定义

AngularJS:$scope.$watch 没有更新从自定义指令上的 $resource 获取的值

在替换 ng-repeat 之前调用自定义指令链接函数

在 angularjs 的自定义指令的 $watch 中不评估表达式

angular js中的directive

什么是vue.js中的自定义指令?