如何在angular js中从指令调用控制器函数

How to call controller function from directive in angular js ?

本文关键字:指令 调用 控制器 函数 angular js      更新时间:2024-05-26

单击按钮打开一个对话框。我想在其中添加无尽的滚动。

问题:

当用户滚动到对话框的末尾时,我想调用控制器中编写的addMoreData()。

对话框的HTML:

 <modal-dialog show='modalShown' width='60%' height='325px' >
   <div id='diaogContainer'>
     <p>Modal Content Goes here<p>
   </div>
</modal-dialog>

控制器:

sampleApp.controller('view3Controller', function($scope) {
     $scope.modalShown = false;
     $scope.toggleModal = function() {
         $scope.modalShown = !$scope.modalShown;
     } 
     **$scope.showMore = function(){
       console.log('showMore');
     }**
   });

对话框指令:

 sampleApp.directive('modalDialog', function() {
   return {
   restrict: 'E',
   scope: {
       show: '='
   },
   replace: true, // Replace with the template below
    transclude: true, 
    link: function(scope, element, attrs) {
    scope.dialogStyle = {};
    if (attrs.width)
        scope.dialogStyle.width = attrs.width;
    if (attrs.height)
        scope.dialogStyle.height = attrs.height;
        scope.hideModal = function() {
        scope.show = false;
    };
 },
 template: "<div class='ng-modal'  ng-show='show'><div class='ng-modal-overlay'ng-click='hideModal()'></div><div class='ng-modal-dialog' hello **scrolly='showMore()'** ng-style='dialogStyle'><div class='ng-modal-close' ng-click='hideModal()'>X</div><div class='ng-modal-dialog-content' ng-transclude></div></div></div>"
  };
});

加载更多数据的指令:

 sampleApp.directive('hello', function () {
  return {
    restrict: 'A',
    link: function (scope, element, attrs) {
        var raw = element[0];
        element.bind('scroll', function () {
            console.log(raw.scrollTop +'-------'+raw.offsetHeight+'----'+raw.scrollHeight);
            if (raw.scrollTop + raw.offsetHeight >= raw.scrollHeight) {
            // here is problem
            // I am not able to call function through this attr
            //
           **scope.$apply(attrs.scrolly);**
            }
        });
    }
  };
});

不能通过属性将函数传递给指令,但可以通过隔离作用域传递。将要调用的函数的引用传递给指令:

 sampleApp.directive('hello', function () {
  return {
    restrict: 'A',
    scope:{
     onScrollEnd:'&'
    },
    link: function (scope, element, attrs) {
        var raw = element[0];
        element.bind('scroll', function () {
            console.log(raw.scrollTop +'-------'+raw.offsetHeight+'----'+raw.scrollHeight);
            if (raw.scrollTop + raw.offsetHeight >= raw.scrollHeight) {
               scope.onScrollEnd();
            }
        });
    }
  };
});

现在假设您在控制器上定义了addMoreData()函数,您可以将其传递给以下指令:

<div hello on-scroll-end='addMoreData()'></div>

编辑

我认为问题是hello指令无法访问父控制器上的函数,因为modalDialog指令使用的是一个隔离的作用域,因此使父控制器的所有内容都不可见。将函数传递到modalDialog指令的隔离范围:

   scope: {
       show: '=',
       onScrollEnd:'&'
   },

您可以这样尝试。

指令部分

var module = angular.module('direc');
module.directive("direcApp", ['$timeout', function ($timeout) {
    return {
        restrict: 'E',
        templateUrl: "template/template.html",
        compile: function (iel, iattr) {

            return function (scope, el, attr) {
            }
        },
        scope: {
            type: "@",
            items: '=',
            onClick: '&',
            val: "="
        },
        controller: function ($scope) {

            $scope.selectItem = function (selectedItem) {
                $scope.val = selectedItem;
                if (angular.isFunction($scope.onClick)) {
                    $timeout($scope.onClick, 0);
                }
            };
        }
    };
}]);

控制器部分

var app = angular.module('app', ['direc']);
app.controller("appCtrl", ['$scope', '$http', function ($scope, $http) {
    var t = {
        count: function () {
            return $scope.$$watchersCount; // in angular version 4 get total page listener
        },
        val1: "",
        onClick: function () {
            console.log($scope.data.val1);
        },
        items: [{ text: 'Seçenek 1', value: '1' },
        { text: 'Seçenek 2', value: '2' },
        { text: 'Seçenek 3', value: '3' },
        { text: 'Seçenek 4', value: '4' },
        { text: 'Seçenek 5', value: '5' }]
    };
    angular.extend(this, t);
}]);

Html部件

<div ng-controller="appCtrl as data">
            <div><b>Watcher Count : {{data.count()}}</b></div>
            <direc-app items="data.items"
                             val="data.val1"
                             on-click="data.onClick1()"
                           >
            </selection-group>
        </div>
  1. 将数据作为参数添加到指令:scope:{data:"="},而在指令中仅添加data.prush({name:"i am new object"})

  2. 按照前面的答案中的建议,将函数参数添加到指令中。