1

我想使用別人創建的指令來告訴我的指令,當它內部的ngRepeat已完成創建自己。從子指令調用指令功能不工作

我的外部指令有一個隔離範圍,並具有需要由內部指令調用的範圍函數。這是代碼。

angular.module('my.directives') 

.controller('myTableCtrl', function($scope, $element, $attrs) { 

    $scope.tableLoaded = function(tableName){ 
     console.log("Table Loaded"); 
    }; 

}) 

.directive('myTable', function() { 
    return { 
     restrict: 'EA', 
     scope: {}, 
     controller: 'myTableCtrl as myTable' 
    }; 
}) 

.directive('repeatDone', function($timeout) { 
    return function(scope, element, attrs) { 
     if (scope.$last) { 
      $timeout(function(){ 
       scope.$eval(attrs.repeatDone); 
      }); 
     } 
    } 
}); 

我的HTML看起來像這樣。

<my-table> 
    <div ng-repeat="row in tableRows" repeat-done="tableLoaded('main');"></div> 
</my-table> 

之前我添加範圍:{}將mytable的指令,它已經非常迷茫的時候有在頁面上(在tableLoaded函數獲取調用,而是由不對勁兒)多個表,所以我增加了隔離我認爲是最佳實踐的範圍。不幸的是,repeatDone指令現在無法在父myTable指令中看到/調用tableLoaded()函數。

任何幫助將非常感激。

編輯:

只是爲了澄清。 tableLoaded()是myTable指令的一個函數,我希望能夠從repeatDone指令中調用它,然而這可能是table指令內部的元素。除此之外,我不想更改repeatDone指令,repeatDone不需要甚至不需要知道myTable指令。

+0

where where tableRows being defined?它不在您發佈的任何源代碼中。 – user132278

+0

這是我的主頁控制器。另外,我已將表格行模板簡化爲一個div,以便於閱讀。這絕對是有效的,因爲當我從myTable中移除隔離作用域時,表被填充數據並且tableLoaded()函數被正確調用。 – jonhobbs

+0

@jonhobbs爲什麼不使用隔離的範圍,並用'&'將你的函數連接到內部指令? –

回答

1

請看看下面的解決方案。希望這有助於:)

angular.module('my.directives') 

    .controller('myTableCtrl', function($scope, $element, $attrs) { 

    this.tableLoaded = function(tableName){ //bind the function to controller rather than $scope 
     console.log("Table Loaded"); 
    }; 

    }) 

    .directive('myTable', function() { 
    return { 
     restrict: 'EA', 
     scope: {}, 
     controller: 'myTableCtrl as myTable' 
    }; 
}) 

.directive('repeatDone', function($timeout) { 
    return { 
     restrict: 'EA', 
     scope: true, //your child directive might want to inherit stuff from the parent directive's controller maybe 
     require:'?^myTable', //require the parent directive 
     link: function(scope, element, attrs,tableCtrl) { //the controller of myTable is available as 4th param in link function (because of require) 
      if (scope.$last) { 
       $timeout(function(){ 
        //scope.$eval(attrs.repeatDone); 
        tableCtrl.tableLoaded(); //call the function of the parent's directive (the specific instance) 
       }); 
      } 
     } 
    } 
}); 

編輯:

我在想的問題是在每一次裏面有一個repeatDone有多個表的可能性。 您可以做的是,您可以在完成範圍時發出事件並將其捕獲到您所需的控制器/指令中。或者,您也可以傳遞一個唯一的標識符,以便僅捕獲特定的控制器/指令。 這裏的例子:

.directive('repeatDone', function($timeout) { 
    return { 
     restrict: 'EA', 
     link: function(scope, element, attrs) { 
      console.log('in directive'); 
      var targetUID = attrs.target; 
      console.log(targetUID); 
      if (scope.$last) { 
       $timeout(function(){ 

        console.log('repeat-done now');//scope.$eval(attrs.repeatDone); 
        scope.$emit('repeat-done-' + targetUID,{}); 
       }); 
      } 
     } 
    }; 
}); 
在你的餐桌指令

.directive('myTable', function() { 
    return { 
     restrict: 'EA', 
     controller: 'myTableCtrl as myTable' 
    }; 
}) 

,並在表中的控制器:

.controller('myTableCtrl', function($scope, $element, $attrs) { 
    console.log('in table Ctrl'); 
      var self = this; 
      $scope.tableUID = $attrs.tableId; 
      self.tableLoaded = function(){ 
       console.log("Table Loaded"); 
      }; 
      console.log('tableUID' + $scope.tableUID); 
      $scope.$on('repeat-done-' + $scope.tableUID, function(event,args){ 
       console.log('in catcher function'); 
       self.tableLoaded(); 
      }); 
}) 

然後用

<my-table table-id="table1"> 
    <div ng-repeat="row in tableRows" repeat-done target="table1"></div> 
</my-table> 

這裏的工作JSBIN

希望這會有幫助

+0

謝謝Ahsan,但重複完成應該是一個通用指令,可用於任何重複調用範圍鏈上某處的函數。它不應該知道我的表 – jonhobbs

+0

你能證實它可以「在範圍鏈上的某個地方」或者只是直接的父範圍? – AhsanAyaz

+0

repeat-done可以是我的表內深處的任意數量的作用域,但只有table指令會有一個tableLoaded()函數。 – jonhobbs

0

我想你可能需要使用NG-transclude上my-table能夠使用內部元素

+0

這是行不通的,因爲我沒有將模板應用到指令中,所以無處可逃。 – jonhobbs

+0

而且您也在使用controllerAs。你不應該將你的方法綁定到'this'而不是'$ scope'嗎? –

+0

我不確定。通常我的方法在範圍之內。 – jonhobbs