AngularJS:$ viewContentLoaded在部分视图出现之前被触发 [英] AngularJS: $viewContentLoaded fired before partial view appears

查看:147
本文介绍了AngularJS:$ viewContentLoaded在部分视图出现之前被触发的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于局部视图,我想做一些JavaScript东西,我通常会使用 $(document).ready(function(){...})例如将venet监听器绑定到元素。我知道这不适用于AngularJS和部分视图加载到根视图。



因此,我添加了一个监听器监听 $ viewContentLoaded 事件。调用监听器的函数,因此事件被触发,但在我看来,就像在渲染部分视图之前一样。当我在监听器的函数中设置断点并使用firebug进行调试时,我也不会看到这些元素,函数内的jQuery选择也不会查找部分视图的元素。



这是控制器的样子:

  angular.module('docinvoiceClientAngularjsApp')
.controller('LoginController'函数($ scope,$ rootScope){

$ scope。$ on('$ viewContentLoaded',function(event){
console.log(content loaded);
console.log($(#loginForm)); //这里的断点
});

[...]

我想我做错了,因为如果这是一个常见的错误,那么在stackoverflow中有更多的帖子。



当我使用 ui-router ui-view 时,我会给你一个摘录路由文件:

  angular 
.module('docinvoiceClientAngularjsApp',[
'ui.router',
'ngAnimate',
'ngCookies',
'ngResource',
'ngMessages',
'ngRoute',
'ngSanitize',
'ngTouch '
])
.config(function($ routeProvider,$ stateProvider){
$ stateProvider
.state('login',{
url:'/' ,
templateUrl:'components / login / loginView.html',
controller:'LoginController'
})
.run(['$ state',function($ state) {
$ state.transitionTo('login');
}])

[...]

任何帮助是赞赏感谢和善意的问候



更新1:我将错误删除到以下用例:loginView.html如下所示: p>

 < div id =loginContainerstyle =width:300px> 
< form id =loginFormng-submit =login(credentials)ng-if =session.token == undefined>

[...]

一旦我删除 ng-if 从div标签,它的工作原理。事件在渲染DOM之后触发,因此jQuery查找元素。如果 ng-if 附加到div标签,行为如第一次描述。



更新2:如所承诺的,我添加了一个工作演示,显示添加 ng-if 指令时的不同行为。任何人都可以指出正确的方向吗?不要这样坚持登录表单,因为还有更多的用例,我想根据一些表达式删除视图的某些部分,并在部分视图准备就绪之后执行一些JavaScript内容。



您可以在这里找到工作演示:演示

解决方案

这是与角度摘要循环相关的,它是关于帽子下方的角度,数据绑定等。有很好的教程解释这一点。 b
$ b

要解决您的问题,请使用$ timeout,它将使代码在下一个周期执行,如果已经解析了ng-if:



$

  app.controller('LoginController',function($ scope,$ timeout){
$ scope。$ on('$ viewContentLoaded',function(event){
$ timeout(function(){
$ scope.formData.value = document.getElementById(loginForm)。id;
},0);
});
});

修复演示: http://codepen.io/anon/pen/JoYPdv



但是我强烈建议您使用指令任何DOM操作,控制器不是为此。
这是一个如何做的例子:
在AngularJS中轻松实现dom操作 - 单击一个按钮,然后将焦点设置为输入元素


For a partial view I want to do some JavaScript stuff that I usually would do with $(document).ready(function() {...}), e.g. bind venet listeners to elements. I know that this doesn't work for AngularJS and partial views loaded into the "root" view.

Thus I added a listener to the controller that listens to the $viewContentLoaded event. The listener's function is invoked, so the event is fired but it seems to me as if it is before the partial view is rendered. Neither do I see the elements when I set a breakpoint in the listener's function and debug it with firebug, nor does the jquery selection within the function find the partial view's elements.

This is what the controller looks like:

angular.module('docinvoiceClientAngularjsApp')
  .controller('LoginController', function ($scope, $rootScope) {

$scope.$on('$viewContentLoaded', function(event) {
  console.log("content loaded");
  console.log($("#loginForm"));   // breakpoint here 
});

[...]

I guess that I am doing something wrong as there had to be more posts on stackoverflow if this is a common bug.

As I am using ui-router and ui-view, I will give you an excerpt of the routing file:

angular
  .module('docinvoiceClientAngularjsApp', [
    'ui.router',
    'ngAnimate',
    'ngCookies',
    'ngResource',
    'ngMessages',
    'ngRoute',
    'ngSanitize',
    'ngTouch'
  ])
 .config(function ($routeProvider, $stateProvider) {
    $stateProvider
    .state('login', {
        url: '/',
        templateUrl: 'components/login/loginView.html',
        controller: 'LoginController'
    })
    .run(['$state', function ($state) {
        $state.transitionTo('login');
    }])

 [...]

Any help is appreciated. Thanks and kind regards

UPDATE 1: I stripped the error down to the following usecase: The loginView.html looks like the following:

<div id="loginContainer" style="width: 300px">
  <form id="loginForm" ng-submit="login(credentials)" ng-if="session.token == undefined">

[...]

As soon as I remove the ng-if from the div tag, it works as expected. The event is triggered after the DOM is rendered, thus jQuery finds the element. If the ng-if is attached to the div tag, the behaviour is as first described.

UPDATE 2: As promised I added a working demo that shows the different behaviour when adding a ng-if directive. Can anyone point me the right direction? Don't stick to the login form as such, as there are many more use cases where I want to remove certain parts of a view based on some expression and do some JavaScript stuff after the partial view is ready.

You can find the working demo here: Demo

解决方案

This is related to angular digest cycle, it's about how angular works underneath the hood, data binding etc. There are great tutorials explaining this.

To solve your problem, use $timeout, it will make the code execute on the next cycle, whem the ng-if was already parsed:

app.controller('LoginController', function ($scope, $timeout) {
    $scope.$on('$viewContentLoaded', function(event) {
      $timeout(function() {
        $scope.formData.value = document.getElementById("loginForm").id;
      },0);
    });
});

Fixed demo here: http://codepen.io/anon/pen/JoYPdv

But I strongly advise you to use directives do any DOM manipulation, the controller isn't for that. Here is a example of how do this: Easy dom manipulation in AngularJS - click a button, then set focus to an input element

这篇关于AngularJS:$ viewContentLoaded在部分视图出现之前被触发的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆