对于局部视图,我想做一些JavaScript的东西,我通常会用$(document).ready(function(){…}),例如将venet侦听器绑定到元素。我知道这不适用于AngularJS和部分视图加载到“根”视图。
因此,我向侦听$ viewContentLoaded事件的控制器添加了一个监听器。监听器的函数被调用,所以事件被触发,但在我看来,就像在渲染部分视图之前一样。当我在监听器的函数中设置断点并使用firebug进行调试时,我也不会看到这些元素,函数内部的jQuery选择也不会发现部分视图的元素。
这是控制器的外观:
angular.module('docinvoiceClientAngularjsApp') .controller('LoginController',function ($scope,$rootScope) { $scope.$on('$viewContentLoaded',function(event) { console.log("content loaded"); console.log($("#loginForm")); // breakpoint here }); [...]
我想我做错了,因为如果这是一个常见的错误,那么在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:我将错误删除到以下usecase:loginView.html如下所示:
<div id="loginContainer" style="width: 300px"> <form id="loginForm" ng-submit="login(credentials)" ng-if="session.token == undefined"> [...]
一旦我从div标签中删除ng-if,它就按预期工作。事件在渲染DOM之后触发,因此jQuery查找元素。如果ng-if附加到div标签,则行为如前所述。
更新2:如所承诺的,我添加了一个工作演示,显示添加ng-if指令时的不同行为。任何人都可以指出正确的方向吗?不要坚持登录表单,因为还有更多的用例,我想根据一些表达式删除视图的某些部分,并在部分视图准备好之后执行一些JavaScript的东西。
你可以在这里找到工作演示:Demo
解决方法
这与角度摘要循环有关,它是关于罩下方的角度如何,数据绑定等。有很好的教程解释这一点。
要解决您的问题,请使用$ timeout,它将使代码在下一个周期执行,如果已经解析了ng-if:
app.controller('LoginController',$timeout) { $scope.$on('$viewContentLoaded',function(event) { $timeout(function() { $scope.formData.value = document.getElementById("loginForm").id; },0); }); });
固定演示:http://codepen.io/anon/pen/JoYPdv
但是我强烈建议您使用指令进行任何DOM操作,控制器不适用于此。
这是一个如何做的例子:
Easy dom manipulation in AngularJS – click a button,then set focus to an input element