簡體   English   中英

從子指令調用指令函數不起作用

[英]Calling directive function from child directive not working

我正在嘗試使用其他人創建的指令來告訴我的指令,其中的 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>

在我將 scope:{} 添加到 myTable 指令之前,當頁面上有多個表時會變得非常混亂(tableLoaded 函數被調用但被錯誤的孩子調用),所以我添加了我認為最好的隔離范圍實踐。 不幸的是,repeatDone 指令現在無法查看/調用父 myTable 指令中的 tableLoaded() 函數。

任何幫助將非常感激。

編輯:

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

請看下面的解決方案。 希望這可以幫助 :)

    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

希望這可以幫助

我認為您可能需要在my-table上使用 ng-transclude 才能使用內部元素

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM