10

Utworzono dyrektywę przy użyciu niestandardowego popover bootstrap. To działa, pobierając dane wejściowe od użytkownika dla nazwy grupy i ma dwa przyciski do zastosowania tej wartości do modelu i pokazują tę wartość na etykiecie narzędziowej i przycisk do zamknięcia popover. Używam zdarzeń skryptu java popover, Problem polega na tym, że pojedynczy popover działa idealnie, ale kiedy otworzę inny, ten popover nie zamyka się. Potrzebujesz pomocy w zamykaniu innych witryn internetowych, gdy jedna jest otwarta. Oto plnk przedstawiający dyrektywę.AngularJS bootstrap popover custom dyrektywa

Oto kod

var app = angular.module('myApp',[]); 
app.directive('customEditPopover', function() { 
     return { 
      restrict: 'A', 
      template: '<span><i class="fa fa-tags" aria-hidden="true"></i></span>', 
      scope: { 
       'myModel': '=', 
      }, 
      link: function (scope, el, attrs) { 
       scope.label = attrs.popoverLabel; 
       var btnsave = '#' + attrs.popoverSave; 
       var btncancel = '#' + attrs.popoverCancel; 
       var index = attrs.index; 
       $(el).tooltip({ 
        title: '' + (scope.myModel == undefined) ? "" : scope.myModel, 
        container: 'body', 
        placement: 'top' 
       }); 
       $(el).popover({ 
        trigger: 'click', 
        html: true, 
        content: attrs.popoverHtml, 
        placement: attrs.popoverPlacement, 
        container: 'body' 
       }) 
       .on('inserted.bs.popover', function (e) { 
        bindevents(); 
        $('#popovertext' + index).val(scope.myModel); 
       }).on('hidden.bs.popover', function() { 
        Unbindevents(); 
       }); 
       function bindevents() { 
        $(btnsave).bind('click', function() { 
         var text = $('#popovertext' + index).val(); 
         scope.myModel = text; 
         $(el).tooltip('hide') 
         .attr('data-original-title', text) 
         .tooltip('fixTitle') 
         toggle(); 
        }); 
        $(btncancel).bind('click', function() { 
         toggle(); 
        }); 
       } 
       function Unbindevents() { 
        $(btnsave).unbind('click'); 
        $(btncancel).unbind('click'); 
       } 
       function toggle() { 
        $(el).popover('hide'); 
        $(el).click(); 
       } 

      } 
     }; 
    }); 
app.controller('MyController',['$scope',function($scope){ 
    $scope.list=[ 
    { 
     name:'ABC' 
    }, 
    { 
     name:'DEF' 
    }, 
    { 
     name:'GHI' 
    }, 
    { 
     name:'KLM' 
    } 
    ]; 

}]); 

Potrzebujesz pomocy zamykając inne popover podczas otwierania następnego.

+1

Widzę w plucie nic nie działa! – Aravind

+0

Istnieje bootstrap dla dyrektyw kątowych łatwo dostępnych. Polecam, aby użyć tego do nadpisania własnej funkcji jquery .https: //angular-ui.github.io/bootstrap/ – gh9

+0

Jeśli @suzo odpowiedział na twoje pytanie, powinieneś przyznać mu nagrodę – gh9

Odpowiedz

5

Można zamknąć inne popovers gdy show.bs.popover jest wyzwalany, jak pokazano poniżej: Updated Plunkr

$(el).popover({ 
       trigger: 'click', 
       html: true, 
       content: attrs.popoverHtml, 
       placement: attrs.popoverPlacement, 
       container: 'body' 
      }) 
      .on('show.bs.popover', function() { 
       var siblings = $(el).parent().parent().siblings(); 
       siblings.each(function (each){ 
       $(siblings[each]).find('span').popover('hide'); 
       }); 
      }); 
+1

Myślę, że to jest złe sposób robienia tego. Ponieważ opiera się na dyrektywie, która zna kod wywołujący. Oznacza to, że nasza dyrektywa musi teraz wiedzieć, w jaki sposób strona główna/widok/cokolwiek ma strukturę html. Wykonuje to zadanie, ale teraz sprawia, że ​​dyrektywa "wie", jak ma się nazywać, pozostawiając ją nie modularną. – gh9

+1

Tak, to rozwiązanie może być używane tylko w tym przypadku. Jeśli struktura HTML zmieni się, to nie działa.Wciąż próbuję wymyślić lepsze rozwiązanie. – superUser

4

IMO, najbardziej modułowy sposób byłoby skorzystać z usługi, aby śledzić wszystkie otwierane wyskakujące okienka.

Daje to wiele korzyści.

  1. można rozszerzyć usługę śledzić różne typy pop-upów, co pozwala zamknąć wszystkie lub otwierać wszystkie lub zrobić cokolwiek trzeba

  2. Usuwa logikę od kontroli i dyrektyw na śledzenie popups. W ten sposób mogą skupić się na 1 konkretnej rzeczy. Możesz także uruchamiać wiele kontrolerów i okien podręcznych na stronie, dzięki czemu każdy kontroler/popup może być dyskretną jednostką pracy i nie musi martwić się o inne kontrolery/okienka wyskakujące na swoich przedmiotach.

Minusy robi to

  1. Jak skomentował wcześniej można użyć angular bootstrap directives do tego. Uczynienie twojego kodu "czystszym", ponieważ wszystko to dzieje się dla ciebie. To, co nie zostało zrobione, zamyka wszystkie aktywne wyskakujące okienka. Możesz skorzystać z tej samej metody serwisowej, której użyłem i po prostu podłączyć ją do dyrektyw ng-bootstrap.
  2. Wiązanie/rozłączanie zdarzeń JQUERY wydaje się przestać odpowiadać po kliknięciu ponad 8 razy. Nie mam odpowiedzi na pytanie, dlaczego tak jest, ale ogólny pomysł wykorzystania usługi do śledzenia jest nadal aktualny.

Będziesz w stanie wyciąć i wkleić ten kod do pnkr lub skrzynki dev i to zadziała.

// Code goes here 
var app = angular.module('myApp',[]); 

app.factory('popUpService', function() { 
    var activePopups = []; 
    // factory function body that constructs shinyNewServiceInstance 

    return { 
    AddPopup : function(el) 
    { 
    activePopups.push(el); 
    }, 
    CloseAllPopups : function(closeFunction){ 
    for (var i = 0; i < activePopups.length; i++) 
    { 
      closeFunction(activePopups[i]) 

    } 
    } 
    } 

}); 
app.directive('customEditPopover',['popUpService', function (popUpService) { 
     return { 
      restrict: 'A', 
      template: '<span><i class="fa fa-tags" aria-hidden="true"></i></span>', 
      scope: { 
       'myModel': '=', 
      }, 
      link: function (scope, el, attrs) { 
       scope.label = attrs.popoverLabel; 
       var btnsave = '#' + attrs.popoverSave; 
       var btncancel = '#' + attrs.popoverCancel; 
       var index = attrs.index; 
       $(el).tooltip({ 
        title: '' + (scope.myModel == undefined) ? "" : scope.myModel, 
        container: 'body', 
        placement: 'top' 
       }); 
       $(el).popover({ 
        trigger: 'click', 
        html: true, 
        content: attrs.popoverHtml, 
        placement: attrs.popoverPlacement, 
        container: 'body' 
       }) 
       .on('inserted.bs.popover', function (e) { 
        bindevents(); 
        $('#popovertext' + index).val(scope.myModel); 
       }).on('hidden.bs.popover', function() { 
        Unbindevents(); 
       }); 
       function bindevents() { 

       CloseAll(); 

       popUpService.AddPopup($(el)); 

        $(btnsave).bind('click', function() { 
         var text = $('#popovertext' + index).val(); 
         scope.myModel = text; 
         $(el).tooltip('hide') 
         .attr('data-original-title', text) 
         .tooltip('fixTitle') 
        closeCurrent(); 
        }); 
        $(btncancel).bind('click', function() { 
        closeCurrent(); 
        }); 
       } 
       function Unbindevents() { 
        $(btnsave).unbind('click'); 
        $(btncancel).unbind('click'); 
       } 
       function closeCurrent(){ 
        $(el).popover('hide'); 
       // $(el).click(); 
       } 
       function CloseAll() { 

       popUpService.CloseAllPopups(function(popup){ 

        popup.popover('hide'); 
       // popup.click(); 
       }); 

      } 
     } 
     } 
    }]); 
app.controller('MyController',['$scope',function($scope){ 
    $scope.list=[ 
    { 
     name:'ABC' 
    }, 
    { 
     name:'DEF' 
    }, 
    { 
     name:'GHI' 
    }, 
    { 
     name:'KLM' 
    } 
    ]; 

}]);