angularjs 1.7.2 - Как вызвать директивную функцию из контроллера? - PullRequest
0 голосов
/ 31 августа 2018

Как вы вызываете функцию директивы из контроллера?

Я видел несколько ответов на этот вопрос, решение которых похоже на следующее:

https://lennilobel.wordpress.com/tag/calling-directive-from-controller/

Я реализовал это следующим образом:

Директива

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>

Когда я запускаю код, директива указывает, что accessor не определен. В результате, accessor в контроллере не определил myFunc .

Как мне заставить myFunc выполнить?

Я использую угловой 1.7.2

1 Ответ

0 голосов
/ 31 августа 2018

Контроллер компилируется (экземпляр создается с результирующей областью действия) перед директивой.

В этом случае он компилируется быстрее, чем директива может установить функцию доступа.

Быстрый обходной путь для этого - установить задержку перед проверкой наличия средства доступа, использующего сервис $timeout.

Ключ имеет Promise объект, переданный $q.all. Это приведет к небольшой задержке и позволит скомпилировать директиву.

На самом деле вы будете иметь обещания, которые передают какой-либо сетевой вызов на $q.all вместо того, чтобы обойти эту проблему с помощью службы $timeout.

Вот как это будет происходить:

index.html

<div ng-controller="myCtrl as vm">
  <my-directive accessor="vm.accessor"></my-directive>
</div>

script.js

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: '='
    }
  };
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...