如果要完成,请确保DOM已准备就绪
我正在使用ng-if来显示和隐藏一个元素。 当元素出现时,我想调用一个服务,该服务在新元素内滚动到某个孩子(由Id)。 问题是,如果在将元素设置为可见之后尝试调用我的服务函数,那么DOM似乎还没有准备好。
var myApp = angular.module('myApp',[]);
myApp.factory("ScrollService", function () {
return {
scroll: function (id) {
console.log(document.getElementById(id));
}
};
});
function MyCtrl($scope, ScrollService) {
$scope.visible = false;
$scope.toggleVisibility = function () {
$scope.visible = !$scope.visible;
if ($scope.visible) {
ScrollService.scroll("myId"); //output: null
}
};
}
document.getElementById()
将始终为null
。
这里也是一个小提琴,演示了这个问题:http://jsfiddle.net/Dpuq2/
那么有没有什么办法可以在DOM被准备好之后立即触发一个函数?
编辑
使用MinkoGechev的小提琴,我能够在更现实的环境中重现我的错误,并使用指令而不是服务:FIDDLE
这个问题似乎发生了,因为我在ng-if
-container中使用了ng-repeat
:
<div ng-controller="MyCtrl">
<div ng-if="visible">
<div id="myId" data-scroll="itemId">
<div id="xy"></div>
<div ng-repeat="item in items" id="{{ item.number }}">{{ item.number }}</div>
</div>
</div>
<button ng-click="toggleVisibility()">toggle</button>
</div>
这是根据指令加控制器:
var myApp = angular.module('myApp',[]);
myApp.directive("scroll", function () {
return {
scope: {
scroll: '='
},
link: function (scope) {
scope.$watch('scroll', function (v) {
console.log(v, document.getElementById(scope.scroll));
});
},
transclude: true,
template: "<div ng-transclude></div>"
};
});
function MyCtrl($scope) {
$scope.visible = false;
$scope.itemId = "";
$scope.items = [];
for (var i = 1; i < 10; i++) {
$scope.items.push({
number: i,
text: "content " + i
});
}
$scope.toggleVisibility = function () {
$scope.visible = !$scope.visible;
if ($scope.visible) {
$scope.itemId = "3";
}
};
}
所以,只要我切换我的容器的可见性,我设置了我想要滚动的元素的Id:
$scope.itemId = "3"
如果我使用1到10之一的数字(由ng-repeat创建的元素的ID),它将失败。 如果我使用“xy”(位于ng-repeat元素旁边的一个元素的Id),它会成功。
以下是您如何通过指令实现您要查找的效果:
var myApp = angular.module('myApp',[]);
myApp.directive("scroll", function () {
return {
scope: {
scroll: '='
},
link: function (scope) {
scope.$watch('scroll', function (v) {
//The value is true, so the element is visible
console.log(v, document.getElementById('myId'));
});
}
};
});
function MyCtrl($scope) {
$scope.visible = false;
$scope.toggleVisibility = function () {
$scope.visible = !$scope.visible;
};
}
这里是DEMO (打开您的控制台查看日志)。
注意 :AngularJS强制分离关注点,从而导致更具可读性和可维护性的代码。 其中一个,你应该遵循在使用“的角度办法”的规则是把所有DOM操作里面只有指令。
你有没有找到解决你的问题?
既然你提到这个问题似乎与ng-repeat有关,你有没有尝试过“scope。$ last?”?
我绝不是一个有经验的Web开发人员,但我遇到了类似的问题,其中工具提示不会显示ng-repeat“生成”的项目,并且使用“scope。$持续”
举个例子:
AppName.directive('directiveName', function () {
return function (scope, element, attrs) {
if (scope.$last) {
<-- Your code here -->
}
};
});
也许有更多经验的人可以提供更多的意见。
链接地址: http://www.djcxy.com/p/17035.html