带有从外部调用的方法的 AngularJS 指令 [英] AngularJS directive with method called from outside

查看:21
本文介绍了带有从外部调用的方法的 AngularJS 指令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

一些示例玉代码来澄清:

//- 视图本身的控制器div(ng-controller="someController")//- 这是视图本身的一部分,不在指令中div(ng-repeat="元素中的元素")div(ng-click="methodFromDirective(element)") 点击元素 {{$index}} 触发指令//- 这是指令div(一些指令)

someController 在这里我认为不是很重要.它有方法,但没有 methodFromDirective(element) 方法.methodFromDirective(element) 是一个只存在于指令中的方法.

如果我制定指令并在创建时进行一些日志记录,我可以清楚地看到它已创建.但是 methodFromDirective(element) 方法没有公开,所以调用没有正确触发.

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

一些显示指令定义的咖啡脚本(这里忽略缩进错误):

'使用严格'定义 [], () ->someDirective = () ->限制:'A'范围: {显示:'='}嵌入:假templateUrl: 'someTemplateHere.html'控制器 = ($scope) -># 在这里公开方法$scope.methodFromDirective(element)->$scope.theMethod 元素link = (scope, element, attr) -># 这已被记录console.log "init someDirective"# 在外部触发此方法表单失败scope.theMethod = (element)->console.log "用元素触发的方法", JSON.stringify(element)

解决方案

我发现了我的问题.

关于指令的 angularJS 文档 我正在研究 transclude 选项,因为它指出:

<块引用>

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

我将 transclude=falsecontroller 函数结合起来,因为这暴露了该方法,同样来自文档:

<块引用>

精明的读者可能想知道链接和控制器之间的区别是什么.基本的区别是控制器可以暴露一个API,链接函数可以使用require与控制器交互.

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

<块引用>

我们希望能够做的是将指令内部的作用域与外部作用域分开,然后将外部作用域映射到指令的内部作用域.我们可以通过创建我们所谓的隔离范围来做到这一点.为此,我们可以使用指令的范围选项:

因此,即使您使用 transclude=falsecontroller 函数,如果您使用隔离作用域,您仍然无法公开方法!吸取了教训!

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

html

<div ng-controller="Ctrl1"><p>看看我们是否可以从指令中存在的控制器触发一个方法.</p><ul><li><a href="#" ng-click="methodInController()">控制器中的方法</a></li><li><a href="#" ng-click="methodInDirective()">指令中的方法</a></li><简单指令/>

javascript

angular.module('directiveScopeExample', []).controller('Ctrl1', 函数 Ctrl1($scope) {$scope.methodInController = function(){alert('控制器中的方法被触发');};}).directive('simpleDirective', function(){返回 {限制:'E',转置:假,控制器:功能($范围){$scope.methodInDirective = function(){//调用在作用域上定义但仅在指令内定义的方法,这是公开的,因为在 $scope 上的链接函数中定义$scope.showMessage('触发指令中的方法');}}//这就是问题所在,创建一个新的作用域会阻止控制器从指令中调用方法//, 范围: {// 标题: '@'//},链接:功能(范围,元素,属性,tabsCtrl){//在此查看相关代码scope.showMessage = 函数(消息){警报(消息);}},//templateUrl: 'some-template-here.html'};})

I created a directive with a method that should be called from other elements that are not part of the directive. However it looks like this method is not exposed.

Some example jade code to clarify:

//- 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)

The someController isn't too important here I think. It has methods but NOT the methodFromDirective(element) one. The methodFromDirective(element) is a method that exists only in the directive.

If I make a directive and put some logging on creation I can clearly see it's created. However the methodFromDirective(element) method isn't exposed so the calls aren't properly triggered.

The methodFromDirective(element) itself will only work on elements from within the directive's template.

some coffeescript to show the definition of the the directive (ignore indentation errors here):

'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)

解决方案

I found my issue.

From the angularJS documentation on directives I was looking into the transclude option since that states:

What does this transclude option do, exactly? transclude makes the contents of a directive with this option have access to the scope outside of the directive rather than inside.

I combined transclude=false with the controller function since that exposes the method, again from docs:

Savvy readers may be wondering what the difference is between link and controller. The basic difference is that controller can expose an API, and link functions can interact with controllers using require.

However what I missed completely was that I isolated scope within my directive. From docs:

What we want to be able to do is separate the scope inside a directive from the scope outside, and then map the outer scope to a directive's inner scope. We can do this by creating what we call an isolate scope. To do this, we can use a directive's scope option:

So even if you use transclude=false and the controller function you'll still fail to expose methods if you use isolated scope! Lesson learned!

While figuring out what went wrong I also made a fiddle for better understanding: 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>

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'
     };
  })  

这篇关于带有从外部调用的方法的 AngularJS 指令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆