AngularJS指令使用从外部调用的方法

hcp*_*cpl 9 angularjs-directive angularjs-scope

我创建了一个带有方法的指令,该方法应该从不属于该指令的其他元素调用.但是看起来这个方法没有公开.

一些示例玉代码澄清:

//- a controller for the view itself
div(ng-controller="someController")

    //- this is part of the view itself, not within the directive
    div(ng-repeat="element in elements") 
        div(ng-click="methodFromDirective(element)") click element {{$index}} to trigger directive

    //- this is the directive
    div(some-directive)
Run Code Online (Sandbox Code Playgroud)

someController我认为这不是太重要.它有方法但不是方法methodFromDirective(element).这methodFromDirective(element)是一种仅存在于指令中的方法.

如果我制定一个指令并对创建进行一些记录,我可以清楚地看到它已创建.但是,该methodFromDirective(element)方法未公开,因此未正确触发调用.

methodFromDirective(element)本身只适用于指令模板中的元素.

一些coffeescript显示指令的定义(忽略缩进错误):

'use strict'
define [], () ->

someDirective = () ->
    restrict: 'A'
    scope: {
        show: '='
    }
    transclude: false
    templateUrl: 'someTemplateHere.html'

    controller = ($scope)  ->

       # exposing the method here
       $scope.methodFromDirective(element)->
           $scope.theMethod element

    link = (scope, element, attr) ->

       # this is logged
       console.log "init someDirective"

       # triggering this method form outside fails
       scope.theMethod = (element)->
          console.log "method triggered with element", JSON.stringify(element)
Run Code Online (Sandbox Code Playgroud)

hcp*_*cpl 11

我发现了我的问题.

指令的angularJS文档中我查看了该transclude选项,因为它表明:

这个transclude选项究竟做了什么?transclude使得带有此选项的指令的内容可以访问指令之外的范围而不是内部.

我结合transclude=false了该controller函数,因为它再次从docs暴露了该方法:

精明的读者可能想知道链接和控制器之间的区别.基本区别在于控制器可以公开API,链接功能可以使用require与控制器交互.

然而,我完全错过的是我在指令中隔离了范围.来自docs:

我们希望能够做的是将指令内的范围与外部范围分开,然后将外部范围映射到指令的内部范围.我们可以通过创建我们称之为隔离范围的方法来实现.为此,我们可以使用指令的范围选项:

因此,即使您使用transclude=falsecontroller函数,如果使用隔离范围,您仍然无法公开方法!学过的知识!

在弄清楚出了什么问题的同时,我也做了一个小提琴,以便更好地理解:http://jsfiddle.net/qyBEr/1/

HTML

<div ng-app="directiveScopeExample">

    <div ng-controller="Ctrl1">

        <p>see if we can trigger a method form the controller that exists in the directive.</p>

        <ul>
            <li><a href="#" ng-click="methodInController()">Method in Controller</a></li>
            <li><a href="#" ng-click="methodInDirective()">Method in Directive</a></li>
        </ul>

    <simple-directive/>
    </div>
</div>
Run Code Online (Sandbox Code Playgroud)

JavaScript的

angular.module('directiveScopeExample', [])

  .controller('Ctrl1', function Ctrl1($scope) {

      $scope.methodInController = function(){
          alert('Method in controller triggered');
    };

  })
  .directive('simpleDirective', function(){

      return {
      restrict: 'E',
      transclude: false,

      controller: function($scope){
          $scope.methodInDirective = function(){
              // call a method that is defined on scope but only within the directive, this is exposed beause defined within the link function on the $scope
              $scope.showMessage('Method in directive triggered');
          }
      }
      // this is the issue, creating a new scope prevents the controller to call the methods from the directive
      //, scope: {
      //  title: '@'
      //}
      , link: function(scope, element, attrs, tabsCtrl) {
         // view related code here
          scope.showMessage = function(message){
              alert(message);
          }
      },
      //templateUrl: 'some-template-here.html'
     };
  })  
Run Code Online (Sandbox Code Playgroud)


Aiv*_*oss 8

在指令的链接函数中调用私有方法非常简单

   dropOffScope = $('#drop_off_date').scope();
   dropOffScope.setMinDate('11/10/2014');
Run Code Online (Sandbox Code Playgroud)

哪里

   $('#drop_off_date') - jQuery function
   setMinDate() - private function inside directive
Run Code Online (Sandbox Code Playgroud)

您甚至可以从外太空调用指令功能.

  • “甚至来自外太空” (2认同)