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 项目很开心。
我开始在我的应用程序中使用 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 项目很开心。