繁体   English   中英

在ng-repeat指令范围内,Angular $ index始终为0

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM