我在我的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有几个开始执行函数的时间点。如果您正在寻找类似jQuery的

$(document).ready();

你可能会发现这个类比在angular中非常有用:

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

当您想要操作DOM元素时,这个选项非常有用。它只在所有te元素加载后才开始执行。

UPD:当你想改变css属性时,上面所说的是有效的。然而,当您想测量元素属性(如宽度、高度等)时,有时它就不起作用了。在这种情况下,你可能想试试这个:

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

其他回答

为什么不试试angular文档提到的https://docs.angularjs.org/api/ng/function/angular.element呢?

angular.element(回调)

我已经在$onInit(){…}函数。

 var self = this;

 angular.element(function () {
        var target = document.getElementsByClassName('unitSortingModule');
        target[0].addEventListener("touchstart", self.touchHandler, false);
        ...
    });

这对我很管用。

Angular有几个开始执行函数的时间点。如果您正在寻找类似jQuery的

$(document).ready();

你可能会发现这个类比在angular中非常有用:

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

当您想要操作DOM元素时,这个选项非常有用。它只在所有te元素加载后才开始执行。

UPD:当你想改变css属性时,上面所说的是有效的。然而,当您想测量元素属性(如宽度、高度等)时,有时它就不起作用了。在这种情况下,你可能想试试这个:

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

如果你得到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上放置了对自身的引用。最终对我有用的是在这个scope属性上设置一个手表,并在初始化后才启动我的函数。

// $scope.myGrid property will be created by the grid itself
// The grid will have a loadedRows property once initialized

$scope.$watch('myGrid', function(newValue, oldValue) {
    if (newValue && newValue.loadedRows && !oldValue) {
        initializeAllTheGridThings();
    }
});

使用未定义的值调用监视程序几次。然后,当网格创建并具有预期的属性时,可以安全地调用初始化函数。第一次使用非未定义的newValue调用观察者时,oldValue仍然是未定义的。

这是我在外部控制器内部使用coffeescript的尝试。它运行得相当好。请注意settings.screen。xs|sm|md|lg是我在应用程序中包含的非丑陋文件中定义的静态值。这些值是根据同名媒体查询大小的Bootstrap 3官方断点:

xs = settings.screen.xs // 480
sm = settings.screen.sm // 768
md = settings.screen.md // 992
lg = settings.screen.lg // 1200

doMediaQuery = () ->

    w = angular.element($window).width()

    $scope.xs = w < sm
    $scope.sm = w >= sm and w < md
    $scope.md = w >= md and w < lg
    $scope.lg = w >= lg
    $scope.media =  if $scope.xs 
                        "xs" 
                    else if $scope.sm
                        "sm"
                    else if $scope.md 
                        "md"
                    else 
                        "lg"

$document.ready () -> doMediaQuery()
angular.element($window).bind 'resize', () -> doMediaQuery()