您好我有一个从后端获取数据的工厂。然后使用控制器(如下所示)处理该数据,并使用ng-repeat在网页中注入。由于系统的异步性质,当我尝试操作窗口时遇到麻烦。例如,我需要使用window.scrollTo函数,但只有AFTER数据被完全处理并在屏幕上显示ng-repeat。
正如你在这里看到的,我试图在控制器的早期使用一个承诺。但它不起作用:window.scrollTo总是在数据在屏幕上处理完毕之前处理。我想我需要的是一种实际强制数据处理完成的方法,然后才处理window.scrollTo函数,但我不知道如何。
.controller('myCtrl',
function ($scope, prosFactory, fieldValues, $q ) {
$scope.listpros = function() {
prosFactory.getPros()
.success(function(data, status) {
var defer = $q.defer();
defer.promise
.then(function () {
$scope.prosItems = data; // pass data to ng repeat first
})
.then(function () {
$window.scrollTo(0, 66); // then scroll
});
defer.resolve();
}).error(function(data, status) {
alert("error");
}
);
};
我尝试在scrollTo函数上使用2000超时,但是由于互联网速度的变化,它有时会将滚动延迟很多,或者某些时候还不够。
答案 0 :(得分:0)
在这种情况下,承诺无济于事,因为它无论如何都没有连接到ng-repeat
进程。但是,当最后一个项目被处理时,您可以使用自定义指令$emit
事件。您的控制器可以监听该特定事件并根据您的需要做出反应。
This answer向您展示了如何实现这一目标,它甚至还带有一个Plunker。
编辑:控制DOM创建的一般方法
在AngularJS世界中,DOM元素受指令控制,在这种情况下受到监督。我上面链接的答案扩展了ng-repeat
指令的行为,但你可以对任何DOM元素做同样的事情。指令creation-emitter
看起来像这样:
myModule.directive('creationEmitter', function () {
return {
restrict: 'A',
compile: function compile(tElement, tAttrs, transclude) {
return {
pre: function (scope, iElement, iAttrs, controller) {
scope.$emit('preCompile', iElement)
},
post: function (scope, iElement, iAttrs, controller) {
scope.$emit('postCompile', iElement)
}
}
},
link: function (scope, iElement, iAttrs) {
scope.$emit('link', iElement)
}
};
});
您现在可以在控制器中监听DOM中给定元素之上的所有事件(对于子元素使用$broadcast
)。
答案 1 :(得分:0)
它可以链接承诺并进行中间处理。 不朽的回调必须返回下一个将收到的内容。
我认为这种方法没有任何直接问题:
prosFactory.getPros()
.then(processCb)
.then(doSomethingWithProcessedDataCb)
.catch(errorCb)
.finally(scrollWindowCb)
查看documentation,它实际上相当不错。