数据检索和显示后推迟处理

时间:2013-12-19 11:55:52

标签: angularjs

您好我有一个从后端获取数据的工厂。然后使用控制器(如下所示)处理该数据,并使用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超时,但是由于互联网速度的变化,它有时会将滚动延迟很多,或者某些时候还不够。

2 个答案:

答案 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,它实际上相当不错。