对于部分视图,我想做一些我通常会用 $(document).ready(function() {...})
做的 JavaScript 东西,例如将 venet 侦听器绑定到元素.我知道这不适用于 AngularJS 和加载到根"视图中的部分视图.
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.
因此,我在控制器中添加了一个监听器来监听 $viewContentLoaded
事件.调用了侦听器的函数,因此触发了该事件,但在我看来,它好像是在呈现局部视图之前.当我在侦听器的函数中设置断点并使用 firebug 对其进行调试时,我也看不到元素,函数内的 jquery 选择也找不到局部视图的元素.
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.
这是控制器的样子:
angular.module('docinvoiceClientAngularjsApp')
.controller('LoginController', function ($scope, $rootScope) {
$scope.$on('$viewContentLoaded', function(event) {
console.log("content loaded");
console.log($("#loginForm")); // breakpoint here
});
[...]
我想我做错了,因为如果这是一个常见错误,stackoverflow 上必须有更多帖子.
I guess that I am doing something wrong as there had to be more posts on stackoverflow if this is a common bug.
由于我使用的是ui-router和ui-view,我给大家摘录一下路由文件:
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
更新 1: 我将错误简化为以下用例: loginView.html 如下所示:
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">
[...]
只要我从 div 标签中删除 ng-if
,它就会按预期工作.该事件在 DOM 渲染后触发,因此 jQuery 找到了元素.如果 ng-if
附加到 div 标签,则行为如第一次描述的那样.
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.
更新 2: 正如我所承诺的,我添加了一个工作演示,显示了添加 ng-if
指令时的不同行为.谁能指出我正确的方向?不要拘泥于登录表单,因为还有更多用例,我想根据某些表达式删除视图的某些部分,并在部分视图准备好后执行一些 JavaScript 操作.
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.
要解决您的问题,请使用 $timeout,它会使代码在下一个周期执行,而 ng-if 已被解析:
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);
});
});
此处修复演示:http://codepen.io/anon/pen/JoYPdv
但我强烈建议你使用指令来进行任何 DOM 操作,控制器不适合那样做.以下是如何执行此操作的示例:AngularJS 中的简单 dom 操作 - 单击按钮,然后将焦点设置到输入元素
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
上一篇:当焦点在复选框/处理previewTextInput在主窗口中,而不是让孩子控制偷字符previewTextInput不会触发复选框、而不是、字符、焦点
下一篇:GetInterfaces()返回泛型接口类型,与全名= NULL全名、接口类型、GetInterfaces、NULL