[英]Angular $index always 0 inside ng-repeat directive scope
我有一系列重复的项目。 在ng-repeat中有一个指令需要传递给它的$ index。 指令内的repeaterIndex始终为0,即使该数组中有多个项目。 我也试过传递类别而不是$ index,它总是传递给指令的第一个类别。
这是控制器代码
angular.module('app')
.controller('ImageUploadCtrl', ['$scope', 'fooSvc',
function ($scope, fooSvc) {
fooSvc.getCategories().then(function(response){
$scope.categories = response.data;
}, function (error) {
console.log(error);
});
$scope.uploadCategoryPhoto = function(categoryIndex){
//upload photo
};
}]);
ng-repeat代码 :
<li ng-repeat="category in categories">
<my-directive repeater-index="{{$index}}" image-object="category.newFeaturedImageObj" callback="uploadCategoryPhoto"></my-directive>
</li>
myDirective.js
angular.module('app')
.directive('myDirective', [function() {
return {
restrict: 'E',
scope: {
callback: '=',
imageObject: '=',
repeaterIndex: '@'
},
templateUrl: 'app/myDirective/myDirective.html',
link: function(scope) {
scope.handleFileSelect = function(element) {
var file = element.files[0];
var reader = new FileReader();
reader.onload = function (event) {
scope.$apply(function() {
scope.imageObject.image = event.target.result;
scope.callback(scope.repeaterIndex);
});
};
reader.readAsDataURL(file);
};
}
};
}]);
myDirective.html
<div>
<input id="upload" type="file" accept="image/*"
onchange="angular.element(this).scope().handleFileSelect(this)"/>
<label for="upload">
Upload
</label>
</div>
如果我在另一个地方使用该指令并给它一个不同的回调属性,如callback =“fooBar”,该指令仍然会调用uploadCategoryPhoto。 就好像页面上的所有指令都采用第一个指令的属性。
你的代码看起来还不错。 一切按预期工作。
看看jsfiddle
angular.module('ExampleApp', []) .controller('ExampleController', function($timeout) { var me = this; $timeout(function() { me.categories = [{ newFeaturedImageObj: {} }, { newFeaturedImageObj: {} }, { newFeaturedImageObj: {} }]; }, 5000); this.uploadCategoryPhoto = function(categoryIndex) { console.log('uploadCategoryPhoto', categoryIndex); //upload photo }; }) .directive('myDirective', [ function() { return { restrict: 'E', scope: { callback: '=', imageObject: '=', repeaterIndex: '@' }, template: `<div> <input id="upload" type="file" accept="image/*" onchange="angular.element(this).scope().handleFileSelect(this)"/> <label for="upload"> Upload </label> </div> `, link: function(scope) { scope.handleFileSelect = function(element) { var file = element.files[0]; var reader = new FileReader(); reader.onload = function(event) { scope.$apply(function() { scope.imageObject.image = event.target.result; console.log('repeaterIndex', scope.repeaterIndex); scope.callback(scope.repeaterIndex); }); }; reader.readAsDataURL(file); }; } }; } ]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script> <div ng-app="ExampleApp"> <div ng-controller="ExampleController as vm"> Appear after 5 seconds. <ul> <li ng-repeat="category in vm.categories"> <my-directive repeater-index="{{$index}}" image-object="category.newFeaturedImageObj" callback="vm.uploadCategoryPhoto"></my-directive> </li> </ul> </div> </div>
我相信,你应该先申报 “类别”。 目前,$ scope.categories正在回调中声明,但是回调代码执行时DOM已经呈现并且“类别” undefined
。 如果首先声明“类别”并将其分配给数组,则将为“类别”注册观察者,并且当回调执行并分配数据时,观察者将触发并更新DOM。
angular.module('app')
.controller('ImageUploadCtrl', ['$scope', 'fooSvc',
function ($scope, fooSvc) {
$scope.categories = []; // declare "categories"
fooSvc.getCategories().then(function(response){
$scope.categories = response.data;
}, function (error) {
console.log(error);
});
$scope.uploadCategoryPhoto = function(categoryIndex){
//upload photo
};
}]);
请试一试。
您在指令模板中使用硬编码ID将输入与标签相关联。 问题是这个ID在ng-repeat中重复,并且不再是唯一的。
解决方案是通过在输入元素周围包装label元素来删除ID:
myDirective.html
<div>
<label>
Upload
<input type="file" accept="image/*"
onchange="angular.element(this).scope().handleFileSelect(this)"/>
</label>
</div>
或者您可以使用repeater-index参数生成唯一ID:
myDirective.html
<div>
<input id="upload{{$repeaterIndex}}" type="file" accept="image/*"
onchange="angular.element(this).scope().handleFileSelect(this)"/>
<label for="upload{{$repeaterIndex}}">
Upload
</label>
</div>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.