2016-10-29 3 views
0

У меня возникли проблемы с компонентом менеджера галереи, где вы можете добавлять/удалять изображения.Ошибка ngRepeat при удалении дочерней директивы из родительской директивы

Это HTML код обработчика галереи:

<img src = '{{snapshot}}' > 
<div class = 'md-button l3' is-file ng-model = 'picture' blob-url = 'snapshot'>Upload</div> 
<div class = 'md-button l3' ng-click = 'article.pictures.push(picture)'>Add</div> 

<div gallery-manager = 'article.pictures'></div> 

Ниже директивы:

.directive("galleryManager", function($compile){ 
     var controllerFn = function($scope, $element, $attrs){ 
      var self = this;   
      self.removeItemAt = function($index){ 
       self.pictures.splice($index, 1); 
       $compile($element)($scope); <--Note this 
      } 
     } 
     var linkFn = function($scope, $element, $attrs){ 
     } 

     return { 
      template:"<div gallery-item = 'picture' ng-repeat = 'picture in galleryManagerCtrl.pictures track by $index'></div>", 
      restrict:"A", 
      controller:controllerFn, 
      controllerAs:"galleryManagerCtrl", 
      bindToController:{ 
       pictures:"=galleryManager", 
      } 
     } 
    }) 
    .directive("galleryItem", function(FileService){ 
     var linkFn = function($scope, $element, $attrs, galleryManagerCtrl){ 
      $scope.galleryItemCtrl.galleryManagerCtrl = galleryManagerCtrl; 
     } 
     var controllerFn = function($scope, $element, $attrs){ 
      var self = this; 
      if (self.item instanceof File){ 
       FileService.buildBlobUrl(self.item).then(function(blobUrl){ 
        self.thumb = blobUrl; 
       }) 
      } 
     } 
     return{ 
      template:"<img src = '{{galleryItemCtrl.thumb}}'>"+ 
       "<a class = 'delete' ng-click = 'galleryItemCtrl.galleryManagerCtrl.removeItemAt($index)'>&times</span></a>", 
      restrict:"A", 
      require:"^galleryManager", 
      link:linkFn, 
      controller:controllerFn, 
      bindToController:{ 
       item:"=galleryItem", 
      }, 
      controllerAs:"galleryItemCtrl" 
     } 
    }) 

Сейчас директива работает хорошо при добавлении элементов, но проблемы возникают при удалении Предметы; перед использованием: $ compile ($ element) ($ scope) после удаления в галерее всегда удалялся последний элемент, хотя массив изображений удалял правильный элемент, поэтому я добавил строку $ compile после удаления элемента.

Проблема заключается в том, что, хотя галерея теперь делает то, что я хочу, он продолжает бросать ошибку после компиляции (после полного следа, может быть, это может помочь кому-то):

angular.js:13920 TypeError: Cannot read property 'insertBefore' of null 
    at after (http://localhost/www/project/admin/bower_components/angular/angular.js:3644:13) 
    at JQLite.(anonymous function) [as after] (http://localhost/www/project/admin/bower_components/angular/angular.js:3728:17) 
    at domInsert (http://localhost/www/project/admin/bower_components/angular/angular.js:5282:35) 
    at Object.move (http://localhost/www/project/admin/bower_components/angular/angular.js:5488:9) 
    at ngRepeatAction (http://localhost/www/project/admin/bower_components/angular/angular.js:29865:26) 
    at $watchCollectionAction (http://localhost/www/project/admin/bower_components/angular/angular.js:17385:13) 
    at Scope.$digest (http://localhost/www/project/admin/bower_components/angular/angular.js:17524:23) 
    at ChildScope.$apply (http://localhost/www/project/admin/bower_components/angular/angular.js:17790:24) 
    at HTMLAnchorElement.<anonymous> (http://localhost/www/project/admin/bower_components/angular/angular.js:25890:23) 
    at defaultHandlerWrapper (http://localhost/www/project/admin/bower_components/angular/angular.js:3497:11) 

Это, кажется, пришел от watchCollection в ngRepeatDirective.

У меня такое ощущение, что у меня нет чего-то основного, но я не могу понять, что сейчас происходит, поэтому я пришел, чтобы спросить, прежде чем копать в угловой код.

Заранее спасибо.

EDIT

Добавлен рабочий пример: http://codepen.io/sergio0983/pen/rMEMoJ?editors=1010

EDIT 2

Удален $ компилировать из рабочего образца, это делает его работу, да, но бросает ошибку; и, кроме того, я думаю, что реальная проблема в другом месте. В рабочей образце вы можете увидеть, как имена файлов обновляются, когда вы удаляете элемент, но изображения сохраняют свой первоначальный порядок.

+0

не должны использовать '$ декомпилировать '.Часы 'ng-repeat' изменят представление для вас – charlietfl

+0

Если я не использую компиляцию, всегда удаляется последняя фотография (ну, на самом деле: модель верна, но в представлении всегда удаляется lastPicture); я попытаюсь сделать пример кода – sergio0983

+0

индексирование, вероятно, не так, всегда лучше делать собственное индексирование в контроллере и не полагаться на '$ index' ... особенно если используются какие-либо фильтры – charlietfl

ответ

1
  1. добавить addPicture() функцию к вашему mainController (который добавит постоянный уникальный идентификатор ро объекта изображения):

    .controller("mainController", function($scope){ 
        $scope.article = {pictures:[]}; 
        $scope.addPicture = function addPicture (picture) { 
        // set unique ID 
        picture.id = $scope.article.pictures.length; 
        $scope.article.pictures.push(picture); 
        }; 
    }) 
    
  2. изменения добавить кнопку HTML, чтобы:

    <div class='md-button l3' ng-click='addPicture(picture)'>Add</div> 
    
  3. изменение брокерga lleryManager к track by picture.id:

    <div gallery-item='picture' 
        ng-repeat='picture in galleryManagerCtrl.pictures track by picture.id'></div> 
    
  4. изменить removeItemAt() функцию ($compile не нужен здесь):

    self.removeItemAt = function removeItemAt (id) { 
        // find index for the picture with given id 
        id = self.pictures.findIndex((item) => item.id === id); 
        self.pictures.splice(id, 1); 
    } 
    

    модифицированное codepen: http://codepen.io/anon/pen/mrZOre?editors=1010

+0

Кажется, что я работаю, я буду отмечать как принятый ответ, как только смогу его развернуть (не могу проверить его прямо сейчас). Сначала нужно проверить, добавляются ли поля к файловому объекту с некоторым побочным эффектом, и идентификатор должен быть назначен внутри контроллера директивы. – sergio0983

Смежные вопросы