angularjs 1.7.2-如何从控制器调用指令函数?

angularjs 1.7.2-如何从控制器调用指令函数?,angularjs,Angularjs,如何从控制器中调用指令的函数 我已经看到了这个问题的许多答案,其解决方案与以下类似: 我已按以下方式实施: 指示 angular.module('myApp').directive('myDirective', ['$log', function ($log) { function link(scope, element, attributes) { //function that a controller can call scope.myFunc

如何从控制器中调用指令的函数

我已经看到了这个问题的许多答案,其解决方案与以下类似:

我已按以下方式实施:

指示

angular.module('myApp').directive('myDirective', ['$log',

function ($log) {

    function link(scope, element, attributes) {

        //function that a controller can call
        scope.myFunc = function () {
            //Do Something
        };


        //if the user has provided an accessor, attach the function
        if (scope.accessor) {
            scope.accessor.myFunc = scope.myFunc;
        }
    }

    return {
        link: link,
        restrict: 'E',
        templateUrl: 'app/myTemplate.html',
        scope: {
            accessor: '=',
        }
    }
}
控制器

angular.module('myApp').controller('myCtrl', ['$log', '$q',

function ($log, $q) {

    var vm = this;

    // empty object that the directive will attach myFunc to
    vm.accessor = {};

    $q
        .all([
            //Service Call
        ])
        .then(function (results) {
                //manipulate the results of the service call using the
                //directives function
                vm.callDirective();
            },
            function (err) {
                $log.debug('$q.all err:', err);
            });



    vm.callDirective = function () {
        if (vm.accessor.myFunc) {
            vm.accessor.myFunc();
        } else {
            $log.error('umm, I don\'t have a function to call');
        }
    };
}
HTML模板

<div ng-controller="myCtrl">
    <myDirective accessor="vm.accessor"></myDirective>
</div>
当我运行代码时,该指令指示访问器未定义。因此,控制器中的访问器没有定义myFunc

如何让myFunc执行


我使用的是angular 1.7.2

该控制器编译为一个实例,该实例是在指令之前使用生成的作用域创建的

在这种情况下,它的编译速度比指令设置访问器函数的速度快

一个快速的解决方法是在使用$timeout服务检查是否存在访问者之前设置延迟

关键是将一个Promise对象传递给$q.all。这将导致一个小的延迟,并允许编译指令

实际上,您将获得一些网络调用传递给$q.all的承诺,而不是使用$timeout服务来解决此问题

这将是如何进行的:

index.html


如果我没记错的话,让我们来看一下局部范围。您尝试过使用var-vm吗?即使使用var,而不是let,我也有同样的问题,指令中未定义访问器。但我同意,在这种情况下应该使用var,因为我希望vm是全局可访问的。我怀疑在访问器对象可用之前,该指令已链接。尝试将myFunktion分配包装为$timeout。或者,您可以在外部div上尝试ng if=vm.accessor,以确保在链接指令时定义了访问器。
<div ng-controller="myCtrl as vm">
  <my-directive accessor="vm.accessor"></my-directive>
</div>
const myApp = angular.module('myApp', []);

myApp.directive('myDirective', ['$log', myDirective]);

myApp.controller('myCtrl', ['$scope', '$timeout', '$log', '$q', myCtrl]);

function myCtrl($scope, $timeout, $log, $q) {
  const vm = $scope.vm;

  // empty object that the directive will attach myFunc to
  vm.accessor = {};

  vm.callDirective = () => {
    if (vm.accessor.myFunc) {
      vm.accessor.myFunc();
    } else {
      $log.error("umm, I don't have a function to call");
    }
  };

  const handleSuccess = results => {
    //manipulate the results of the service call using the
    //directives function
    vm.callDirective();
  };

  const handleError = err => {
    $log.debug('$q.all err:', err);
  };

  $q.all([
    //Service Call
    $timeout()
  ])
    .then(handleSuccess)
    .catch(handleError);
}

function myDirective($log) {

  //function that a controller can call
  const myFunc = function() {
    //Do Something
    $log.info('Calling assessor myFunc');
  };

  const link = function(scope) {
    //if the user has provided an accessor, attach the function
    if (scope.accessor) {
      scope.accessor.myFunc = myFunc;
    }
  };

  return {
    link: link,
    restrict: 'E',
    templateUrl: 'mydirective.html',
    scope: {
      accessor: '='
    }
  };
}