从子指令调用父指令函数

时间:2017-03-09 03:50:40

标签: javascript angularjs directive

我需要将父指令中的值传递给子指令,更新它,然后将其传回。当我传入父函数,并创建双向绑定时,我收到错误:

  

scope.updateItem不是函数

我该如何做到这一点?

父指令模板:

<div>
   <custom-phrases item-to-update="item" update-item="updateItem"></custom-phrases>
</div>

父指令js:

angular
  .module('app')
  .directive('itemlist',
    function($rootScope, $state) {
      return {
        restrict: 'EA',
        templateUrl: 'directives/cms/itemlist/itemlist.tpl.html',
        scope: {
        },
        link: function(scope, element) {
          // This will be called from child directive with updated item
          scope.updateItem = function(item) {
            console.log('Updating item from itemlist', item);
          };
        },
      };
    });

Child指令js:

angular
  .module('app')
  .directive('customPhrases',
    function($rootScope) {
      return {
        restrict: 'AE',
        scope: {
          itemToUpdate: '=',
          updateItem: '=',
        },
        templateUrl: 'directives/cms/customPhrases/custom_phrases_directive.tpl.html',
        link: function(scope, element) {

          // do stuff to scope.itemToUpdate...
          // then pass it back to parent directive
          scope.updateItem(scope.itemToUpdate);
          ...

注意:我还尝试&绑定一个函数:

<div>
   <custom-phrases item-to-update="item" update-item="updateItem(item)"></custom-phrases>
</div>

然后在child指令中,将其更改为:

scope: {
  itemToUpdate: '=',
  updateItem: '&',
},

如果我登录日志scope.updateItem我得

  

TypeError:scope.updateItem不是函数

1 个答案:

答案 0 :(得分:0)

的index.html

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8" />
    <title>Nested Directives</title>

    <link rel="stylesheet" href="./../../../lib/bootstrap/css/bootstrap.min.css">
    <style>
        body{
            margin: 5px 10px;
        }
    </style>
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
    <script src="app.js"></script>
</head>

<body ng-app="app">
    <div class="continer">
            <my-tabs>
<!--  first pane starts-->
      <my-pane title="Home">
<!--      home page contains jumbotron-->
        <div class="jumbotron">
          <h1>Home Page</h1>
          <p>This is a simple hero unit, a simple jumbotron-style component for calling extra attention to featured content or information.</p>
          <p><a class="btn btn-primary btn-lg" href="#">Learn more</a></p>
        </div>
<!--      home page jumbotron ends-->
      </my-pane>
<!--      first pane ends-->

<!--  second pane starts-->
      <my-pane title="Login">
<!--      login form start-->
        <form class="form-horizontal">
          <div class="form-group">
            <label for="inputEmail3" class="col-sm-2 control-label">Email</label>
            <div class="col-sm-10">
              <input type="email" class="form-control" id="inputEmail3" placeholder="Email">
            </div>
          </div>
          <div class="form-group">
            <label for="inputPassword3" class="col-sm-2 control-label">Password</label>
            <div class="col-sm-10">
              <input type="password" class="form-control" id="inputPassword3" placeholder="Password">
            </div>
          </div>
          <div class="form-group">
            <div class="col-sm-offset-2 col-sm-10">
              <button type="submit" class="btn btn-default">Sign in</button>
            </div>
          </div>
        </form>
<!--        login form ends-->
      </my-pane>
<!--  second pane ends-->
    </my-tabs>
    </div>

</body>

</html>

app.js

var app = angular.module('app', []);

app.directive('myTabs', function() {
  return {
    restrict: 'E',
    transclude: true,
    scope: {},
    controller: function MyTabsController($scope) {
      var panes = $scope.panes = [];

      $scope.select = function(pane) {
        angular.forEach(panes, function(pane) {
          pane.selected = false;
        });
        pane.selected = true;
      };

      this.addPane = function(pane) {
        if (panes.length === 0) {
          $scope.select(pane);
        }
        panes.push(pane);
      };
    },
    templateUrl: 'my-tabs.html'
  };
})
.directive('myPane', function() {
  return {
      // ^^ prefix means that this directive searches for the controller on its parents
    require: '^^myTabs',
    restrict: 'E',
    transclude: true,
    scope: {
      title: '@'
    },
    link: function(scope, element, attrs, tabsCtrl) {
      tabsCtrl.addPane(scope);
    },
    templateUrl: 'my-pane.html'
  };
});

MY-pane.html

<div class="tab-pane" ng-show="selected">
  <h4>{{title}}</h4>
  <hr/>
  <div ng-transclude></div>
</div>

MY-tabs.html

<div class="tabbable">
  <ul class="nav nav-tabs nav-inverse">
    <li ng-repeat="pane in panes" ng-class="{active:pane.selected}">
      <a href="" ng-click="select(pane)">{{pane.title}}</a>
    </li>
  </ul>
  <div class="tab-content" ng-transclude></div>
</div>