2016-10-29 152 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) 

這似乎來來自ngRepeatDirective的watchCollection。

我有一種感覺,我錯過了一些基本的東西,但是現在看不到什麼,所以在這裏,我在挖角碼之前先問一下。

預先感謝您。

編輯

新增工作示例: http://codepen.io/sergio0983/pen/rMEMoJ?editors=1010

EDIT 2

刪除$從工作樣品編譯,這使得它的工作,是的,但拋出的錯誤;另外,我認爲真正的問題在別處。在工作示例中,您可以看到刪除某個項目時文件名如何更新,但這些圖片保持其原始順序。

+0

不應該使用'$編譯'。'ng-repeat'手錶會改變你的視圖 – charlietfl

+0

如果我不使用編譯,總是最後一張照片被刪除(好吧,不是真的:模型是正確的,但視圖總是刪除lastPicture);我會嘗試做一個代碼示例 – sergio0983

+0

索引可能是不正確的,總是最好在控制器中做自己的索引並且不要依賴'$ index' ...特別是如果使用任何過濾器 – charlietfl

回答

1
  1. 添加addPicture()功能到您mainController(這將增加恆定唯一IDロ圖象對象):

    .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 lleryManagertrack 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

似乎有用,我會盡快將其標記爲已接受的答案(現在無法對其進行測試)。想要先檢查是否將字段添加到文件對象有一些副作用,並且,應該在指令的控制器內分配ID。 – sergio0983