2016-01-13 75 views
1

自定义指令按钮我有一个按钮指令,如下所示(Plunker是here):与确认弹出

<button type="button" 
     data-confirm-popup-btntext="Reject" 
     data-confirm-popup-text="Do you want to reject" 
     data-confirm-popup-header="Reject" 
     data-confirm-popup-click="reject(obj)" 
     class="btn btn-danger btn-xs" 
     data-ng-class="{disabled : disable}" 
     data-ng-if="show"></button> 

data-confirm-popup-btntext的按钮上的文字。我不想要的。我也不想data-confirm-popup-click。相反,我想使用ng-click

我的理念是,任何视图都会有任何按钮。如果我在处理之前需要显示一个确认对话框,我会向该按钮添加一个属性(指令),该指令将处理所有事情。

此外,我无法在当前实施中添加<span class'bootstrap-icon'></span> Reject

所以我的期望指令的结果如下:

<button type="button" 
     data-confirm-popup-header="Reject" 
     data-confirm-popup-text="Do you want to reject" 
     <!--Above line two line will add confirm dialog functionality --> 
     data-ng-click="reject(obj)" 
     class="btn btn-danger btn-xs" 
     data-ng-class="{disabled : disable}" 
     data-ng-if="show"><span>Any HTML</span>Reject</button> 

我试图用trnsculation更换假的,真实的,但没能实现这一功能。

+0

您可以使用** ng-click =“dialogFun()”**并编写一个函数** dialogFun **,在其中添加确认弹出类或将其css从隐藏改为阻止。 – AndreaM16

+0

不,我有很多按钮。每个按钮都有'ng-click'功能。我想构建这个指令以便于集成。由于某些按钮需要此功能,有些则不需要。 –

+0

哦,我明白了,那么你应该定义一个属性指令,它使我之前编写的内容成为可能,并在需要时将其包含在内。当我在家时,我会尽力实施它。 – AndreaM16

回答

1

我用你plunker和改变app.js,除去14行至年底,并更换该指令应该让你你想要的点;

app.directive("confirmPopupText",confirmPopupText); 
    confirmPopupText.$inject = ['$uibModal', '$compile', '$parse']; 
    function confirmPopupText ( $modal, $compile, $parse){ 
     var directive = {}; 
     directive.restrict = 'A'; 
     directive.link= function(scope, elem, attrs) { 

      // get reference of ngClick func 
      var model = $parse(attrs.ngClick); 

      // remove ngClick and handler func   
      elem.prop('ng-click', null).off('click'); 

      elem.bind('click' , function(e) { 
       e.stopImmediatePropagation(); 
       console.log('Clicked'); 

       $modal.open({ 
        template: '<div class="modal-header">'+attrs.confirmPopupHeader+'</div>'+'<div class="modal-body">'+attrs.confirmPopupText+'</div>'+'<div class="modal-footer">'+'<button class="btn btn-primary" data-ng-click="ok()">Yes</button>'+'<button class="btn btn-warning" data-ng-click="cancel()">No</button>'+'</div>', 
        controller: function($scope, $uibModalInstance) { 
         $scope.ok = function() { 
          $uibModalInstance.close(); 

          // this line will invoke ngClick func from outer scope 
          model(scope); 
         }; 
         $scope.cancel = function() { 
          $uibModalInstance.dismiss('cancel'); 
         }; 
        } 
       }); 

      }); 
     }; 
     return directive; 
    } 

因此,你可以使用这样的HTML;

<button type="button" 
    data-confirm-popup-header="Reject" 
    data-confirm-popup-text="Do you want to reject" 
    <!--confirmPopupText directive will add confirm dialog functionality --> 
    data-ng-click="reject(obj)" 
    class="btn btn-danger btn-xs" 
    data-ng-class="{disabled : disable}" 
    data-ng-if="show"><span>Any HTML</span>Reject</button> 

更新plunker链接:https://plnkr.co/edit/Bmcqqe32Px25pFCf0Mus?p=preview

+0

不错。高超。正是我在找什么。让我试试我的工作空间。你在这里使用了$ parse。这是魔术。 :) 感谢你的回答。 –

+0

您可以从$ parse service获取任何JavaScript字符串形式的句子的函数。那么你可以使用这个函数在任何给定的范围内评估这个句子,是的,它是不可思议的:) – ibrahimb

0

link函数中,您可以取消/注册事件处理程序并执行任何DOM操作。所以你可以在这里添加确认功能和按钮内容和类。在绑定自己的处理程序之前,重新使用ng-click处理程序解除绑定“click”事件。

return {  
    priority: 1, 
    compile: function(elem, attr) { 
     var text = attr.confirmPopupText; 
     var callback = $parse(attr.ngClick); 
     elem.html('<span>Any HTML</span>Reject'); 
     elem.addClass('btn btn-danger btn-xs'); 

     return function(scope, elem, attr) { 
     elem.unbind('click').bind('click', function(event) { 
      var result = $window.confirm(text); // use $modal here instead   
      callback(scope, {result: result, $event : event}); 
      scope.$apply(scope.ngClick); 
     }); 
     } 
    } 
} 

您可以使用此指令

<div ng-app="app" ng-controller="Main as view"> 
    <button data-confirm-popup-text="Do you want to reject" 
      confirm-button ng-click="view.onConfirm($event, result)"> 
    </button> 
</div> 

https://jsfiddle.net/9huoL1wL/4/

0

基于Erik Chen's answer,可以覆盖或修改AngularJS任何服务,包括指令:

app.config(function($provide){ 
    $provide.decorator('ngClickDirective', ['$delegate', function($delegate) { 
     //$delegate is array of all ng-click directive 
     //in this case frist one is angular buildin ng-click 
     //so we remove it. 
     $delegate.shift(); 
     return $delegate; 
    }]); 
}); 

app.directive('ngClick', function($rootScope) { 
    return { 
    restrict: 'A', 
    priority: 100, 
    link: function($scope, element, attr) { 
     element.bind('click', function($event) { 
     // emit event to manage modal if 'popup' attr is exist 
     if (attr.hasOwnProperty('popup')) { 
      // and pass arguments 
      $scope.$emit('popup-click', { $scope, element, attr }); 
     } else { 
      // else just execute default 'ng-click' handler 
      $scope.$apply(attr.ngClick) 
     } 
     }) 
    } 
    } 
}) 

而且在工厂管理弹出窗口:

app.factory('popupService', function($rootScope) { 
    $rootScope.$on('popup-click', function(e, args) { 
     // click with popup attr observer 
     // there needs to be your code to manage modal 
     // you can pass any params for example as 'popup-title="i am a title"' and get it there with 'args.attr' 
     if (confirm(args.attr.popupText || 'Default text')) { 
      args.$scope.$apply(args.attr.ngClick) 
     } else { 
      // nothing to do 
     } 
    }); 
    return {}; 
}); 

我创建了JSFiddle来显示完整的例子。

希望它能帮助你。

+0

这也是ng-clik覆盖的一个很好的例子。但是在每个点击事件中,它都会检查'if(attr.hasOwnProperty('popup'))'我想。 –