通过attrs从子指令调用父指令方法

时间:2016-01-21 08:27:43

标签: angularjs angularjs-directive

这是情景:

<export-team>
 <ul>
  <li>
   <button buy-ticket="{{data}}" buy-callback="onBuyTicket()">buy</button>
  </li>
  <li>
   <button buy-ticket="{{data}}" buy-callback="onBuyTicket()">buy</button>
  </li>
 </ul>
</export-team>

buyTicket指令

(function() {
  'use strict';

  angular
    .module('myApp')
    .directive('buyTicket', buyTicket);

  /** @ngInject */
  function buyTicket($parse, ngDialog, authService, APPCONFIG, $rootScope, shareToken, contestsFactory, shareCurrentTicket, shareIdSession, shareSessionAAMS, $location) {
    var vm = this; 
    var directive = {
      restrict: 'A',      
      link : function(scope, element, attributes) {

        var buyCompatible = attributes['buyCompatible'];


        function addZero(i) {
            if (i < 10) {
                i = "0" + i;
            }
            return i;
        }        

        var buyTicket = function(contest) {          

            var d = new Date();       
            var y = d.getFullYear();
            var m = addZero(d.getMonth()+1);
            var day = addZero(d.getDate());
            var h = addZero(d.getHours());
            var min = addZero(d.getMinutes());
            var s = addZero(d.getSeconds());
            var date = ''+y+m+day+h+min+s+'';
            var transactionId = $rootScope.TRANSACTIONID;

            var currentTOKEN = shareToken.get();
            var data =  {
                  idSessione:currentTOKEN, // ->TOKEN
                  userAgent:navigator.userAgent,
                  sessioneAAMS:contest.aams_session_id, 
                  gameId:APPCONFIG.GAME_ID,
                  transactionId:transactionId,
                  dateTime:date,
                  buyIn:contest.buy_in
              } 

            var dialogLoading = ngDialog.open({ 
              closeByDocument : false,
              closeByEscape : false,
              showClose : false,
              id : 'ft-modal-loading',
              controller: ['$scope', function($scope){
                $scope.bodyUrl = 'app/components/modals/body/loading.html';     
                $scope.title = 'Acquisto Ticket';
                $scope.error = 'Il sistema sta procedendo all\'acquisto del ticket';
              }]
            });




            contestsFactory.buyTicket(data).success(function(response){

              dialogLoading.close();            


              if (response.esito == "0") {    
                if (!buyCompatible) {

                  shareCurrentTicket.set(response.ticketSogei);
                  shareSessionAAMS.set(contest.aams_session_id);
                  shareIdSession.set(contest.id_session);                  
                  $location.path('my-contests/'+contest.id_contest+'/'+contest.contest_status);  
                }      

              } else {
                var message = response.descrizione;                
                var ids = ngDialog.getOpenDialogs();

               var dialogError = ngDialog.open({ 
                  id : "ft-modal-error-2",
                  controller: ['$scope', function($scope){
                    $scope.bodyUrl = 'app/components/modals/body/error.html';     
                    $scope.title = 'Errore';
                    $scope.error = message;
                  }]
                });         
              }
            })
            .error(function(){



                var dialogErrorNotEndled = ngDialog.close('ft-modal-loading');


                ngDialog.open({ 
                  id : 'ft-modal-error',
                  controller: ['$scope', function($scope){
                    $scope.bodyUrl = 'app/components/modals/body/error.html';     
                    $scope.title = 'Errore';
                    $scope.error = 'Il servizio non è attualmente disponibile';
                  }]
                });         
            })            
        }        

        var openConfirmBuyTicket = function(contest) {
          contest = JSON.parse(contest);

            if (ngDialog.isOpen('ft-modal-contest-detail')) {
              ngDialog.close('ft-modal-contest-detail');    
            };



          if (!authService.isLogged()) {
            ngDialog.open({
              controller: ['$scope', function($scope){
                $scope.bodyUrl = 'app/components/modals/body/not_logged.html';     
                $scope.title = 'Spiacenti';
                $scope.error = 'Devi essere loggato per poter partecipare ad un contest';
              }]
            }); 
          } else {
            ngDialog.openConfirm({
              controller: ['$scope', function($scope){
                $scope.title = 'CONFERMA';
                $scope.bodyUrl = 'app/components/modals/body/confirm_buy.html';
                $scope.contest_name = contest.name_contest;
                $scope.buy_in = contest.buy_in;
                $scope.currency = APPCONFIG.CURRENCY_SYMBOL;
              }],
            }).then(function (confirm) {

              buyTicket(contest);

            }, function(reject) {

            });       
          }   

        } 

        element.on('click', function(e){
          var contest = attributes['buyTicket'];
          openConfirmBuyTicket(contest);
        })               
      }
    };

    return directive;
  }

})();

导出指令

(function() {
  'use strict';

  angular
    .module('myApp')
    .directive('exportTeam', exportTeam);

  /** @ngInject */
  function exportTeam(contestsFactory, ngDialog, APPCONFIG, formatDateFactory) {
    var vm = this; 
    var directive = {
      restrict: 'AE',    
      transclude: true,  
      controller : function($scope) {
        $scope.test = function() {
          alert('hey');
        }
      },
      link : function(scope, element, attributes) {
        element.on('click', function(e){
            var ticket = attributes['exportTeam'];
            var id_session = attributes['idsession'];
            scope.openExportTeamDialog(ticket, id_session, false);
        })


        scope.openExportTeamDialog = function(ticket, aams_session_id, afterSave) {
              ngDialog.open({
                id : 'ft-modal-exportTeam-detail',
                className : 'ngdialog ngdialog-theme-default ft-dialog-exportTeam',
                  controller: ['$scope', 'contestsFactory', 'APPCONFIG', function($scope, contestsFactory, APPCONFIG){
                  $scope.title = "Aggiungi contest compatibili";
                  $scope.bodyUrl = 'app/components/modals/body/exportTeam.html';
                  $scope.contentLoading = true;
                  $scope.currency = APPCONFIG.CURRENCY_SYMBOL;
                  $scope.afterSave = afterSave;         
                  $scope.CompatibleContests = [];
                  contestsFactory.getCompatibleContests(ticket).then(function(response){
                    angular.forEach(response.data[0], function(item, i){
                      var multientryOptions = [];
                      if(item.multientry > 1) { 
                        item.isMultientry = false;
                        var n = parseInt(item.multientry);
                        for (i = 1; i <= n; i++) { 
                            multientryOptions.push({
                              text : i+" team",
                              value : i
                            })
                        }      
                        item.multientryOptions = multientryOptions;                  
                        item.multientryOptionSelected = multientryOptions[0];
                      }else{
                        item.isMultientry = true;
                      };

                    })
                    $scope.CompatibleContests = response.data[0];

                    $scope.contentLoading = false;
                  })


                  }]
              });  

        } 


        scope.openExportTeamDialog('N3E94100A725F9QG', 'M3E921013C6DCFCT', false);


      }
    };

    return directive;
  }

})();

buy-ticket指令对我希望能够调用<export>指令的onBuyTicket方法的响应进行http调用。

我正在努力了解这样做的最佳方法。

谢谢大家

4 个答案:

答案 0 :(得分:0)

  

此示例向您展示如何从指令

调用函数      

在这个示例中,您可以看到我们只是在指令中插入数据,然后我们处理指令中的数据和其他操作。

&#13;
&#13;
var app = angular.module("app", []);
        app.controller("ctrl", function ($scope) {

            $scope.dataFromYourController = [
                { name: "Concert Jennifer", value: 200 },
                { name: "007", value: 100 }
            ];

        })
        .directive("export", function () {
            var template = "<div>" +
                "<ul>" +
                "<li ng-repeat=\"array in arrays\">" +
                    "<button ng-click=\"onBuyTicket()\">buy Ticket {{array.name}}</button><hr>" +
                "</li>" +
                "</ul>" +
                "</div>";
            return {
                restrict: "E",
                template: template,
                scope: {
                    data: "="
                },
                link: function (scope, elem, attrs, ngModel) {
                    scope.arrays = scope.data;

                    scope.onBuyTicket = function () {
                      alert("calling function from directive");
                    }

                }
            };
        })
&#13;
<!doctype html>
<html ng-app="app" ng-controller="ctrl">
<head>
</head>
<body>
  
    <h1>call action from your directive</h1>
    <export data="dataFromYourController"></export>


    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>  
</body>
</html>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

使用$ parent

<button buy-ticket="{{data}}" buy-callback="$parent.onBuyTicket()">buy</button>

所以expor指令类似于:

var directive = { 
 restrict: 'AE',
 template: '<ng-tansclude></ng-transclude>',
 transclude: true,
 controller : function($scope) { 
   $scope.onBuyTicket = function() { 
    alert('hey'); 
   } 
 } 
}

更新:

见羽毛球:

https://plnkr.co/edit/fmyJ4oPLvTiI0TzO7h1b?p=preview

这实际上取决于你可以调用什么以及你不能基于范围...这里如果你从export指令中删除范围将在没有$ parent的情况下工作,因为export会与父代共享相同的范围(主要观点)

答案 2 :(得分:0)

@eesdil

var directive = {
  restrict: 'AE',    
  transclude: true,  
  controller : function($scope) {
    $scope.onBuyTicket = function() {
      alert('hey');
    }
  }
}

我可以从买票指令中调用它吗?

答案 3 :(得分:0)

将子指令中的事件传递给父指令(或控制器)的最佳方法是使用$emit method of the scope

您要做的是参加ng-click活动,通过$http电话获取更多信息,以及$emit活动,其中包含您的父指令要使用的其他信息(或控制器)。

HTML

<button buy-ticket="data" ng-click="onBuyTicket()">buy</button>

指令:

angular.module("myApp").directive("buyTicket", function($http) {
    function linkFn(scope,elem,attrs) {
        scope.onBuyTicket = function() {
            var buyData = scope.$eval(attrs.buyTicket);
            var url = someFunction(buyData);
            $http.get(url).then (function (response) {
                var httpData = response.data;
                scope.$emit("buyTicket.click", buyData, httpData);
            });
        };
    };
    return {
        restrict: "AE",
        link: linkFn
    };
});

在父控制器中:

$scope.$on("buyTicket.click", function (buyData, httpData) {
    console.log(buyData);
    console.log(httpData);
}); 

请注意,我使用$eval methodbuy-ticket属性命名的变量中获取数据。

为事件选择名称时,我建议在事件的名称中包含该指令的名称。它清楚地说明了事件的来源,并且不太可能在其他地方重复。