我在我的angular控制器中有一个函数,我希望这个函数在文档就绪时运行,但我注意到angular在创建dom时运行它。

 function myController($scope)
 {
     $scope.init = function()
     {
        // I'd like to run this on document ready
     }

     $scope.init(); // doesn't work, loads my init before the page has completely loaded
 }

有人知道我该怎么做吗?


当前回答

如何在页面加载中执行angular控制器函数? 快速查找:

// register controller in html
<div data-ng-controller="myCtrl" data-ng-init="init()"></div>

// in controller
$scope.init = function () {
    // check if there is query in url
    // and fire search in case its value is not empty
};

这样,您就不必等到文档准备好了。

其他回答

我们可以使用angular.element(document).ready()方法来附加文档就绪时的回调函数。我们可以像这样简单地在控制器中附加回调:

angular.module('MyApp', [])

.controller('MyCtrl', [function() {
    angular.element(document).ready(function () {
        document.getElementById('msg').innerHTML = 'Hello';
    });
}]);

http://jsfiddle.net/jgentes/stwyvq38/1/

如何在页面加载中执行angular控制器函数? 快速查找:

// register controller in html
<div data-ng-controller="myCtrl" data-ng-init="init()"></div>

// in controller
$scope.init = function () {
    // check if there is query in url
    // and fire search in case its value is not empty
};

这样,您就不必等到文档准备好了。

$scope.$on('$ViewData', function(event) {
//Your code.
});

如果你得到getElementById调用返回null这样的东西,这可能是因为函数正在运行,但是ID还没有时间加载到DOM中。

试着延迟使用Will的答案(朝向上方)。例子:

angular.module('MyApp', [])

.controller('MyCtrl', [function() {
    $scope.sleep = (time) => {
        return new Promise((resolve) => setTimeout(resolve, time));
    };
    angular.element(document).ready(function () {
        $scope.sleep(500).then(() => {        
            //code to run here after the delay
        });
    });
}]);

这个问题的答案

$scope.$watch('$viewContentLoaded', 
    function() { 
        $timeout(function() {
            //do something
        },0);    
});

是唯一一个在我测试的大多数情况下都有效的方法。在一个包含4个组件的示例页面中,所有组件都从一个模板构建HTML,事件的顺序为

$document ready
$onInit
$postLink
(and these 3 were repeated 3 more times in the same order for the other 3 components)
$viewContentLoaded (repeated 3 more times)
$timeout execution (repeated 3 more times)

所以$document.ready()在大多数情况下是无用的,因为在angular中构造的DOM可能还远没有准备好。

但更有趣的是,即使在$viewContentLoaded触发后,仍然无法找到感兴趣的元素。

只有在执行$timeout之后才找到它。请注意,尽管$timeout的值为0,但在它执行之前已经经过了近200毫秒,这表明该线程被暂停了相当长一段时间,可能是因为DOM在主线程中添加了角模板。从第一个$document.ready()到最后一个$timeout执行的总时间将近500毫秒。

在一个特殊的情况下,设置了组件的值,然后在$timeout期间更改了text()值,$timeout值必须增加,直到它工作为止(即使在$timeout期间可以找到该元素)。第三方组件中的某些异步操作导致值优先于文本,直到足够的时间过去。另一种可能是$scope。$evalAsync,但是没有尝试。

我仍然在寻找这样一个事件,它告诉我DOM已经完全稳定下来,并且可以对其进行操作,以便所有的用例都能正常工作。到目前为止,任意的超时值是必要的,这意味着这充其量是一个拼凑,可能无法在缓慢的浏览器上工作。我还没有尝试过JQuery的选项,比如liveQuery和publish/subscribe,它们可能有用,但肯定不是纯angular的。