获取对在ng repeat中创建的元素的JavaScript引用
我正在尝试获取在获取对在ng repeat中创建的元素的JavaScript引用,javascript,angularjs,angularjs-ng-repeat,Javascript,Angularjs,Angularjs Ng Repeat,我正在尝试获取在ng repeat中创建的,以便在第三方库中添加内容 尝试1: <div ng-init="init()"> <div ng-repeat="item in items"> <div id="{{ item.id }}"></div> </div> </div> $scope.init = function() { for (var i in items) { var eleme
ng repeat
中创建的
,以便在第三方库中添加内容
尝试1:
<div ng-init="init()">
<div ng-repeat="item in items">
<div id="{{ item.id }}"></div>
</div>
</div>
$scope.init = function() {
for (var i in items) {
var element = document.getElementById(items[i].id);
generateInnerHtml(element);
}
};
$scope.init=函数(){
对于(项目中的var i){
var element=document.getElementById(items[i].id);
generateInnerHtml(元素);
}
};
尝试2:
<div ng-init="init()">
<div ng-repeat="item in items">
<div id="{{ item.id }}" ng-init="addContent(item.id)"></div>
</div>
</div>
$scope.addContent = function(id) {
var element = document.getElementById(id);
generateInnerHtml(element);
};
$scope.addContent=函数(id){
var元素=document.getElementById(id);
generateInnerHtml(元素);
};
尝试3:
<div ng-init="init()">
<div ng-repeat="item in items">
<div id="{{ item.id }}" ng-init="addContent(this)"></div>
</div>
</div>
$scope.addContent = function(element) {
generateInnerHtml(element);
};
$scope.addContent=函数(元素){
generateInnerHtml(元素);
};
对于所有三次尝试,元素
始终为null或未定义。有什么问题吗?在尝试1和2中,您的函数在处理所有角度指令之前运行,因此尚未定义div
的id
您可以将代码包装在$timeout()
中,强制它等待DOM正确生成:
angular.module("myApp", [])
.controller("myController", function($scope, $timeout) {
$scope.addContent = function(id) {
$timeout(function() {
var element = document.getElementById(id);
generateInnerHtml(element);
}, 0);
};
})
请参见此处的演示:.在尝试#1和#2中,您的函数在处理所有角度指令之前运行,因此尚未定义div
的id
您可以将代码包装在$timeout()
中,强制它等待DOM正确生成:
angular.module("myApp", [])
.controller("myController", function($scope, $timeout) {
$scope.addContent = function(id) {
$timeout(function() {
var element = document.getElementById(id);
generateInnerHtml(element);
}, 0);
};
})
请参见此处的演示:。如前所述,在渲染完成之前,您的函数正在运行。但要像@anied提到的那样,将DOM操作放在指令中。这样,您就可以将它与控制器解耦,并且可以轻松地重用它 看 标记:
<div ng-repeat="item in items" data-generated="item"></div>
指令:
app.directive('generated', ['$compile', function($compile) {
var generateInnerHtml = function(e) {
e.innerHTML = '<pre>item = {{vm.item}}</pre>'
};
return {
restrict: 'AE',
scope: {
item: '=generated'
},
controllerAs: 'vm',
bindToController: true,
controller: [function() {
}],
compile: function(element, attr) {
generateInnerHtml(element[0]);
return function(scope, element, attr) {
// Only do this if you need access to scope variables
$compile(element.contents())(scope);
}
}
};
}]);
app.directive('generated',['$compile',function($compile){
var GENERATEINERHTML=函数(e){
e、 innerHTML='item={{vm.item}}'
};
返回{
限制:“AE”,
范围:{
项目:'=已生成'
},
controllerAs:'vm',
bindToController:对,
控制器:[函数(){
}],
编译:函数(元素,属性){
generateInnerHtml(元素[0]);
返回函数(范围、元素、属性){
//仅当需要访问范围变量时才执行此操作
$compile(element.contents())(范围);
}
}
};
}]);
如前所述,在渲染完成之前,您的函数正在运行。但要像@anied提到的那样,将DOM操作放在指令中。这样,您就可以将它与控制器解耦,并且可以轻松地重用它
看
标记:
<div ng-repeat="item in items" data-generated="item"></div>
指令:
app.directive('generated', ['$compile', function($compile) {
var generateInnerHtml = function(e) {
e.innerHTML = '<pre>item = {{vm.item}}</pre>'
};
return {
restrict: 'AE',
scope: {
item: '=generated'
},
controllerAs: 'vm',
bindToController: true,
controller: [function() {
}],
compile: function(element, attr) {
generateInnerHtml(element[0]);
return function(scope, element, attr) {
// Only do this if you need access to scope variables
$compile(element.contents())(scope);
}
}
};
}]);
app.directive('generated',['$compile',function($compile){
var GENERATEINERHTML=函数(e){
e、 innerHTML='item={{vm.item}}'
};
返回{
限制:“AE”,
范围:{
项目:'=已生成'
},
controllerAs:'vm',
bindToController:对,
控制器:[函数(){
}],
编译:函数(元素,属性){
generateInnerHtml(元素[0]);
返回函数(范围、元素、属性){
//仅当需要访问范围变量时才执行此操作
$compile(element.contents())(范围);
}
}
};
}]);
在控制器中保留对DOM元素的引用可能属于角度反模式的范畴。为什么不在ng repeat中的元素上放置一个指令,并在directivelink
函数中执行您需要执行的任何DOM级操作/引用?在控制器中保留对DOM元素的引用可能属于角度反模式的保护范围。为什么不在ng repeat中的元素上放置一个指令,并在指令链接函数中执行您需要执行的任何DOM级操作/引用?@thegreatjedi此视频将澄清它:@thegreatjedi此视频将澄清它: