我正在使用ng-if來顯示和隱藏元素。當元素出現時,我想調用一個服務,該服務在新元素內滾動到某個孩子(由Id)。問題是,如果在將元素設置爲可見之後嘗試調用我的服務函數,那麼DOM似乎還沒有準備好。angularJS:等待ng - 如果完成,確保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是NG-如果被操縱後準備觸發功能?
編輯
使用MinkoGechev的小提琴,我是能夠重現我的錯誤更逼真的環境,並使用替代的服務的指令:FIDDLE
這個問題似乎發生,因爲我使用ng-repeat
內ng-if
-container的:
<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),它會成功。
請,不實現DOM到控制器,使用指令代替 –
@MaximShoustin我沒不是將它實現成一個控制器,而是實現一個服務,我也嘗試使用一個指令,結果相同 – basilikum
@basilikum在一個指令的link()函數中,你確定鏈接元素的DOM這個指令已經準備就緒,那就是在這裏,你必須將元素滾動到他的孩子。 – Blackhole