知道DOM何时在控制器中呈现

时间:2014-01-30 10:51:45

标签: javascript angularjs angularjs-directive angularjs-scope

我正在使用AngularJS,我遇到了问题。我在控制器上有$ watch:

function MyController() {
    $watch('myModel', function() {
        $rootScope.$emit('do-oper');
    });
}

'myModel'也是通过绑定来改变我的DOM。

在我的指令中:

$rootScope.$on('do-oper', function() {
    // Do DOM manipulation
});

问题在于,在发出'do-oper'时,DOM不会使用更新'myModel'进行渲染。如何在呈现DOM之后触发DOM操作?

3 个答案:

答案 0 :(得分:0)

您可以尝试在AngularJS中的app.run内发布事件。

答案 1 :(得分:0)

我不认为在处理像angular等MVC结构时直接操作DOM是一个好主意。你反对这种模式。在MVC中,视图应尽可能被动,监听模型更改以相应更新,不应直接通过代码更新视图。控制器内部的代码也不应该关心何时呈现视图。

使用$timeout有一种解决方法,但我建议您不要这样做。重新设计代码以包含MVC模式是一种更好的解决方案。

解决方法可能是这样的:

$rootScope.$on('do-oper', function() {
    $timeout(function(){
        // Do DOM manipulation
    });
});

此解决方法的另一个大问题是代码可能无意中更新了DOM属性,并且这些更新可能会与角度发生冲突,这可能会导致不可预测的结果。

您可以将指令更改为以下内容:

$rootScope.$on('do-oper', function() {
        //Update properties of directive's scope based on the changed `do-oper`
});

您的指令模板会绑定到作用域的属性以进行相应更新。

答案 2 :(得分:0)

如果您需要通过角度控制之外的操作来响应DOM中的更改,您可能需要检查ng-ScrollSpy directive's code for a potential method: An AngularJS module for navigation highlighting.

特别值得注意的是,在链接功能中我们看到:

angular.element( document ).ready( function() {
                            setup();
                            determiner();
                    });

这表明您可以更改控制器代码,可能是这样的:

angular.element( document ).ready( function() {
                     $watch('myModel', function() {
                        $rootScope.$emit('do-oper');
                     });      
);

可能感兴趣的进一步阅读:http://henriquat.re/directives/advanced-directives-combining-angular-with-existing-components-and-jquery/angularAndJquery.html