2016-01-13 123 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'))'我想。 –