angularjs:仅在 $resource.query 结果返回后显示容器

angularjs: show container only after $resource.query result returned

我开始在我的应用程序中使用 angularjs,但在动态加载服务器结果时遇到了问题。 我有一个资源:

var GroupingTagMachines = $resource('/grouping_tags/:grouping_tag_id/machines', { format: 'json' }, 
                                      { 
                                        query: { method: 'get', cache: true, isArray: true }
                                      });

我在 link 被点击时使用它:

HTML:

<a href data-ng-click="show($event, tag)">click me</a>

JS:

scope.show = function($event, tag) {
    var clicked_link = $($event.currentTarget);
    var tags_list = clicked_link.parent(".grouping-tag").find(".tag-machines");

    if(tags_list.is(":visible")) {
      tags_list.slideUp();
    } else {
      GroupingTagMachines.query({ "grouping_tag_id": tag.id }, function(tag_machines) {
        tag.machines = tag_machines;
        console.log(tag.machines.length + " machines returned");
        tags_list.slideDown();
      });
    }
  };

现在单击 link 时,将显示容器 div(带有向下滑动动画),然后结果显示在里面。 如您所见,我在我的资源回调方法中使容器可见,因此服务器应该在此之前做出响应。

期望的行为是仅在容器可见后显示结果。

有什么建议吗?

看起来问题与同时使用 jQuery 和 Angular 有关。简而言之,Angular 使用 "digest cycles" 来更新屏幕。所以当 jQuery 做的时候 Angular 不知道。

slideDown() 函数有两个参数。第一个是滑动动画的持续时间,第二个是动画完成时可以执行的回调。

尝试使用该回调更新来自服务器的屏幕 w/the 结果:

// 400 ms seems to be the default
tags_list.slideDown(400, function() {
  $scope.$apply(function() {
      tag.machines = tag_machines;
    });
});

编辑: 如果收到 "digest is already in progress" 错误消息,只需取出对 $scope.$apply() 的调用并将服务器结果分配给 tag.machines .

编辑 #2: 看来我的交互有误 b/c 我正在扩展容器,然后添加项目。先添加项目再展开,可以使用$timeout服务:

tag.machines = tag_machines;
// don't forget to inject $timeout into your controller
$timeout(function() { tags_list.slideDown() });

这应该将幻灯片效果延迟到下一个摘要周期。但是,我认为仅通过将项目添加到容器中,容器就会变大,然后最终起到向下滑动的效果。您可能需要一些额外的 CSS 才能正确处理。

此外,如果您放弃 jQuery 并在 Angular 中全部完成,这些问题就会开始消失。我使用 Angular Motion 项目很开心。