首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在子指令中调用父指令的函数

在子指令中调用父指令的函数
EN

Stack Overflow用户
提问于 2015-05-02 17:06:41
回答 2查看 2.3K关注 0票数 3

嗨,我正在尝试制作一个窗格系统,在这个系统中,子指令上的elem.bind('change,.)改变了“选择的”父指令:http://plnkr.co/edit/gc35fuUiJVUhHF4QMAwv?p=preview

代码语言:javascript
复制
(function(angular) {
  'use strict';
  angular.module('docsTabsExample', [])
    .directive('myTabs', function() {
      return {
        restrict: 'E',
        transclude: true,
        scope: {},
        controller: function($scope) {
          var panes = $scope.panes = [];

          $scope.select = function(pane) {
            angular.forEach(panes, function(pane) {
              pane.selected = false;
            });
            pane.selected = true;
          };
          $scope.next = function(pane) {
            select(panes[panes.indexOf(pane)+1]);
          };
          this.addPane = function(pane) {
            if (panes.length === 0) {
              $scope.select(pane);
            }
            panes.push(pane);
          };
        },
        templateUrl: 'my-tabs.html'
      };
    })
    .directive('myPane', function() {
      return {
        require: '^myTabs',
        restrict: 'E',
        transclude: true,
        scope: {
          title: '@'
        },
        link: function(scope, element, attrs, tabsCtrl) {
          tabsCtrl.addPane(scope);
        },
        templateUrl: 'my-pane.html'
      };
    })
    .directive('pf-data', function() {
      return {
        require: '^myPane',
        restrict: 'AEC',
        scope: {
          title: '@'
        },
        link: function(scope, element, attrs, tabsCtrl) {
          console.log("hi");
          element.bind('change', function() {
            scope.next();
            console.log("switch panes");
          });
        }
      };
    });
})(window.angular);

(当您选择性别(无论是男性还是女性)时,我希望它依次转到下一个窗格,但由于范围问题(我对角比较生疏),它永远不会进入子指令的链接属性。

有什么想法吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-05-02 18:29:20

每个指令都定义了一个独立的作用域(除了指令定义的scope成员的内容外,它几乎是空的。因此,当您说scope.next()时,如果它不是在这个集合中,或者不是由link函数显式附加,它就会失败。所以用$scope联系你的父母是行不通的。当然,您不希望通过属性传递函数来泄漏内部细节。这将使这些相互关联的指令落空。

但你有更好的东西。

因为您使用require将您的指令链接到一起,所以您甚至不必费心于这些游戏。在pf-data中,您将定义:

代码语言:javascript
复制
require: ['^myPane', '^myTabs]

这将使您可以直接访问两个控制器。您需要在next指令中公开myTabs。老实说,我会想出一种方法来使用索引,而不是循环遍历所有设置为true和false的窗格。类似于:

代码语言:javascript
复制
var currentPane;
this.next = function() {
  select(nextPane(currentPane));
};

现在,在pf-data中,您可以通过您的link函数访问:

代码语言:javascript
复制
link: function(scope, element, attrs, ctrls) {
      element.bind('change', function() {
        $scope.$apply(function() {
          ctrls[1].next();
          scope.next();
        };
      });
  ...

更新

我从你提供的新Plnkr中分叉出一个新的Plnkr来整合我们已经讨论过的更改。我还从pf-data中删除了require myPane (因为有了transclude,无论如何也不会起作用)。

http://plnkr.co/edit/LP0RYu6AKxeKyhHY5rZP?p=preview

最新情况包括:

  • pf-data变成了pfData --这只是角度的规则之一。您的指令使用camel大小写命名,但在html中以连字符大小写结尾。
  • 我实现了我说过的所有小事情。scope.$apply并将require更改为使用myTabs。正如我们在注释中讨论的那样,您需要在捕获不是角的直接部分的事件时使用$apply,以便向屏幕上的元素发出更新信号。
  • 我将您在myTabs中的所有方法反弹到this上,而不是$scope上。你会需要他们在那里,因为你是通过控制器机制的他们。
  • 我在控制器中维护当前选定的窗格,这样我们就可以只说next(),而不必提供窗格。
票数 4
EN

Stack Overflow用户

发布于 2015-05-02 18:11:29

你是对的-这是一个范围问题。使用隔离作用域时,指令中唯一可用的作用域变量是通过属性传入的。要调用在指令内部的父作用域中定义的next(),将方法传递给带有'&‘绑定的属性:

代码语言:javascript
复制
  scope: {
       title:'@',
       next: '&'
  }

HTML:

代码语言:javascript
复制
 <my-pane next="next()"></my-pane>
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30005109

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档