【问题标题】:angularjs: show container only after $resource.query result returnedangularjs:仅在返回 $resource.query 结果后显示容器
【发布时间】:2015-04-29 23:26:04
【问题描述】:

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

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

点击链接时我会使用它:

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();
      });
    }
  };

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

所需的行为是仅在容器可见后才显示的结果。

有什么建议吗?

【问题讨论】:

  • 显示tags_list.slideDown() 的代码。看起来您正在控制器中进行 DOM 操作,这在 Angular 中不是一个好主意。我猜测 DOM 操作发生在 Angular 的摘要循环之外导致这个问题......但只是预感,直到我们可以看到 slideDown() 函数正在做什么(如果合适,也显示容器的 HTML)。
  • slideDown() 是 jQuery 函数...api.jquery.com/slidedown

标签: angularjs ngresource


【解决方案1】:

看起来问题与同时使用 jQuery 和 Angular 有关。简而言之,Angular 使用“摘要循环”来更新屏幕。所以当 jQuery 做这件事时,Angular 并不知道它。

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

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

// 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 项目时玩得很开心。

【讨论】:

  • 感谢您的帮助,但如果我说得对,恐怕这与我想要实现的目标相反。如果我同意您的建议,则容器将在幻灯片后填充。我希望它先被填充,然后幻灯片才能采取行动。
  • @benams 知道了,我的错。因此,您可以使用$timeout 来触发下一个摘要循环的下滑效果,而不是使用$scope.$apply() 从服务器设置结果。我会把这个添加到我的答案中......
  • 它有效。谢谢。我真的很讨厌使用超时来实现漂亮的 UI,感觉就像一个补丁,但我想我在这里没有太多其他选择......
猜你喜欢
  • 2014-02-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-27
  • 2013-03-09
  • 2021-02-06
相关资源
最近更新 更多