webentwicklung-frage-antwort-db.com.de

Erstellen Sie einen überblendbaren Popover mithilfe von angle-ui-bootstrap

Ich habe den folgenden Code zum Erstellen eines Popovers in meiner Vorlagendatei:

<span class="icon-globe visibility" 
      id="visibilityFor{{post.metaData.assetId}}" 
      popover="{{post.visibilityListStr}}" 
      popover-placement="right" 
      popover-trigger="mouseenter" 
      popover-popup-delay="50" 
      visibility>
</span>

Ich habe ein paar anklickbare Links im Popover. Aber das Problem ist, dass ich nicht in dem erstellten Popover schweben kann. Ich verwies auf den Link http://jsfiddle.net/xZxkq/ Und versuchte, eine Direktive zu erstellen, nämlich. Sichtbarkeit für diesen Zweck.

Hier ist der Code:

myAppModule.directive("visibility", function ($timeout,$rootScope) {
  return {

    controller: function ($scope, $element) {
        $scope.attachEvents = function (element) {
            $('.popover').on('mouseenter', function () {
                $rootScope.insidePopover = true;
            });
            $('.popover').on('mouseleave', function () {
                $rootScope.insidePopover = false;
                $(element).popover('hide');
            });
        }
    },
    link: function (scope, element, attrs) {
        $rootScope.insidePopover = false;

        element.bind('mouseenter', function (e) {
            $timeout(function () {
                if (!$rootScope.insidePopover) {
                    element.popover('show');
                    attachEvents(element);
                }
            }, 200);
        });

        element.bind('mouseout', function (e) {
            $timeout(function () {
                if (!$rootScope.insidePopover) {
                    element.popover('show');
                    attachEvents(element);
                }
            }, 200);
        });

    }
  }
});

Ich bekomme jedoch eine Ausnahme für 'element.popover', da diese nicht definiert ist. Bitte weisen Sie darauf hin, was ich falsch mache und wie ich den eckigen Pop-Up-Befehl vor der Direktive anzeigen/ausblenden kann. Ich verwende eine eckige Ui-Bootstrap-JS-Datei.

9
Adarsh Konchady

Ich weiß nicht, ob dies für das OP relevant ist, aber ich hatte das gleiche Problem und konnte es glücklicherweise lösen.

Undefinierter Fehler

Als Erstes könnte der undefinierte Fehler (zumindest in meinem Fall) der Fall sein, weil Sie die Entwicklungsversion von ui-bootstrap verwenden. In meinem Fall habe ich diese Fehlermeldung erhalten, als ich element.popover binden wollte. Nach dem Hinzufügen der minimierten Version der Bibliothek wurde der Fehler behoben.

Halten Sie den Popover geöffnet, wenn Sie mit der Maus darüber fahren

Dazu habe ich eine benutzerdefinierte Direktive erstellt, die die popover aus der ui-bootstrap-Bibliothek verwendet.

Richtlinie

app.directive('hoverPopover', function ($compile, $templateCache, $timeout, $rootScope) {
var getTemplate = function (contentType) {
    return $templateCache.get('popoverTemplate.html');
};
return {
    restrict: 'A',
    link: function (scope, element, attrs) {
        var content = getTemplate();
        $rootScope.insidePopover = false;
        $(element).popover({
            content: content,
            placement: 'top',
            html: true
        });
        $(element).bind('mouseenter', function (e) {
            $timeout(function () {
                if (!$rootScope.insidePopover) {
                    $(element).popover('show');
                    scope.attachEvents(element);
                }
            }, 200);
        });
        $(element).bind('mouseleave', function (e) {
            $timeout(function () {
                if (!$rootScope.insidePopover)
                    $(element).popover('hide');
            }, 400);
        });
    },
    controller: function ($scope, $element) {
        $scope.attachEvents = function (element) {
            $('.popover').on('mouseenter', function () {
                $rootScope.insidePopover = true;
            });
            $('.popover').on('mouseleave', function () {
                $rootScope.insidePopover = false;
                $(element).popover('hide');
            });
        }
    }
};
});

Diese Direktive akzeptiert auch eine benutzerdefinierte Vorlage für das Popover. Sie sind also nicht nur auf den Titel und Text beschränkt. Sie können Ihre eigene HTML-Vorlage erstellen und sie dem Steuerelement zuführen.

Verwendung

<a href="#" hover-popover>Click here</a>

Hoffe, das hilft jemand anderem in der Zukunft :)

Bearbeiten

Wie gewünscht, ist hier ein Fiddle link . Es fehlt das Styling, sollte aber zeigen, wie es funktioniert.

8
Cosmin Ionascu

Ich habe es sehr sauber gelöst und wollte es teilen:

.popover wird nicht als untergeordnetes Element des uib-popover erstellt. Die Idee ist also, uib-popover mit einem übergeordneten Element und zu umschließen steuern, ein- und ausblenden beim Schweben des übergeordneten Elements.

.popover und uib-popover sind Kinder dieses übergeordneten Elements , also müssen Sie nur noch set popover-trigger = none angeben und Sie haben das, was Sie sind Wünschen nach.

Ich habe ein plunk Beispiel erstellt :

<span ng-init="popoverOpened=false" ng-mouseover="popoverOpened=true" ng-mouseleave="popoverOpened=false">
    <button class="btn btn-default" uib-popover-html="htmlPopover" 
            popover-trigger="none" popover-placement="bottom-left" popover-is-open="popoverOpened" >
       <span>hover me</span>
    </button>
</span>

genießen.

7
oded

Ich denke, Cosmin hat das schwebbare Popover-Recht, aber es scheint die Twitter-Bootstrap-Popover-Methode zu verwenden. Die Idee ist, diesen schwebbaren Popover nur mit AngularJS und einem der Bootstrap-Wrapper für AngularJS zu implementieren, die UI Bootstrap oder AngularStrap sind.

Also habe ich eine Implementierung zusammengestellt, die nur AngularStrap verwendet:

myApp.directive('hoverablePopover', function ($rootScope, $timeout, $popover) {
    return {
        restrict: "A",
        link: function (scope, element, attrs) {

            element.bind('mouseenter', function (e) {
                $timeout(function () {
                    if (!scope.insidePopover) {

                        scope.popover.show();
                        scope.attachEventsToPopoverContent();
                    }
                }, 200);
            });

            element.bind('mouseout', function (e) {
                $timeout(function () {
                    if (!scope.insidePopover) {

                        scope.popover.hide();
                    }
                }, 400);
            });

        },
        controller: function ($scope, $element, $attrs) {

            //The $attrs will server as the options to the $popover.
            //We also need to pass the scope so that scope expressions are supported in the  popover attributes
            //like title and content.
            $attrs.scope = $scope;
            var popover = $popover($element, $attrs);
            $scope.popover = popover;
            $scope.insidePopover = false;

            $scope.attachEventsToPopoverContent = function () {

                $($scope.popover.$element).on('mouseenter', function () {

                    $scope.insidePopover = true;

                });
                $($scope.popover.$element).on('mouseleave', function () {

                    $scope.insidePopover = false;
                    $scope.popover.hide();

                });
            };
        }
    };
});

Wenn Sie ein Popover-Element haben, müssen Sie berücksichtigen, dass Sie über das Element verfügen, das den Popover auslöst, und Sie haben auch das Element mit dem tatsächlichen Popover-Inhalt.

Die Idee ist, das Popover geöffnet zu halten, wenn Sie mit dem tatsächlichen Popover-Inhalt über das Element fahren. Im Falle meiner Direktive kümmert sich die Link-Funktion um das Element, das die Popover-Funktion auslöst, und verknüpft die Ereignisbehandlungsroutinen für Mouseenter/Mouseout.

Der Controller sorgt für die Einstellung des Bereichs und des Popovers selbst über den AngularStrap $ Popover-Dienst. Der Controller fügt das vom AngularStrap-Dienst im Bereich zurückgegebene Popover-Objekt hinzu, sodass es in der Link-Funktion verfügbar ist. Es fügt außerdem eine Methode attachEventsToPopoverContent hinzu, die die Mouseenter/Mouseout-Ereignisse an das Element mit dem Popover-Inhalt anfügt.

Die Verwendung dieser Anweisung ist wie folgt:

  <a title="Popover Title" data-placement="left" data-trigger="manual" data-content="{{someScopeObject}}" content-template="idOfTemplateInTemplateCache" hoverablePopover="">
5
Milen Kovachev

Dort verbringe ich 1 Tag und bekomme endlich eine Lösung.

<button uib-popover="{{dynamicPopover.content}}" 
    popover-trigger="outsideClick" popover-is-open="popoverIsOpen"
    ng-mouseenter="popoverIsOpen = !popoverIsOpen" 
    popover-title="{{dynamicPopover.title}}" type="button" class="btn btn-default">Dynamic Popover</button>

Bitte überprüfen Sie Plunkeer Link Überprüfen Sie nur den Code der Dynamic Popover-Schaltfläche

Vielen Dank,

5
Roni

Sie müssen den Auslöser in einfache Anführungszeichen setzen, aus folgenden Gründen:

<button uib-popover="I appeared on mouse enter!" popover-trigger="'mouseenter'" type="button" class="btn btn-default">Mouseenter</button>
3
programmer

demo: 

https://jsbin.com/fuwarekeza/1/edit?html,output

direktive:

myAppModule.directive('popoverHoverable', ['$timeout', '$document', function ($timeout, $document) {
    return {
        restrict: 'A',
        scope: {
            popoverHoverable: '=',
            popoverIsOpen: '='
        },
        link: function(scope, element, attrs) {
            scope.insidePopover = false;

            scope.$watch('insidePopover', function (insidePopover) {
                togglePopover(insidePopover);
            })

            scope.$watch('popoverIsOpen', function (popoverIsOpen) {
                scope.insidePopover = popoverIsOpen;
            })

            function togglePopover (isInsidePopover) {
                $timeout.cancel(togglePopover.$timer);
                togglePopover.$timer = $timeout(function () {
                    if (isInsidePopover) {
                        showPopover();
                    } else {
                        hidePopover();
                    }
                }, 100)
            }

            function showPopover () {
                if (scope.popoverIsOpen) {
                    return;
                }

                $(element[0]).click();
            }

            function hidePopover () {
                scope.popoverIsOpen = false;
            }

            $(document).bind('mouseover', function (e) {
                var target = e.target;
                if (inside(target)) {
                    scope.insidePopover = true;
                    scope.$digest();
                }
            })

            $(document).bind('mouseout', function (e) {
                var target = e.target;
                if (inside(target)) {
                    scope.insidePopover = false;
                    scope.$digest();
                }
            })

            scope.$on('$destroy', function () {
                $(document).unbind('mouseenter');
                $(document).unbind('mouseout');
            })

            function inside (target) {
                return insideTrigger(target) || insidePopover(target);
            }

            function insideTrigger (target) {
                return element[0].contains(target);
            }

            function insidePopover (target) {
                var isIn = false;
                var popovers = $('.popover-inner');
                for (var i = 0, len = popovers.length; i < len; i++) {
                    if (popovers[i].contains(target)) {
                        isIn = true;
                        break;
                    }
                }
                return isIn;
            }
        }
    }
}]);

html:

<span class="icon-globe visibility" 
      id="visibilityFor{{post.metaData.assetId}}" 
      popover="{{post.visibilityListStr}}" 
      popover-is-open="{{post.$open}}"
      popover-trigger="click" 
      popover-hoverable="true"
      visibility>
</span>
1
b3bkids

Diese Funktion wurde in Angular UI Bootstrap 0.14.0 hinzugefügt und ist dokumentiert hier . Deaktivieren Sie die Trigger und verwenden Sie die popover-is-open-Eigenschaft, um den geöffneten/geschlossenen Zustand manuell zu bestimmen.

0
icfantv

Die einfachste Möglichkeit, ein Mausereignis mit uib-popover zu haben Sehen Sie sich das Funktionsbeispiel unten an! Sie brauchen kein uib-tabset , ich hatte ein Problem mit uib-tabset und fügte dieses Beispiel hinzu.

<uib-tabset>
      <uib-tab>
        <uib-tab-heading>
          Tab 1
        </uib-tab-heading>
        <div>

          <span ng-mouseover="popoverIsOpen = true" 
                ng-mouseleave="popoverIsOpen = false">
            <button uib-popover-template="'includeFile.html'"
                    popover-trigger="outsideClick" 
                    popover-is-open="popoverIsOpen"
                    popover-placement="right"
                    type="button" class="btn btn-default">
              Dynamic Popover
            </button>
        </span>

        </div>
        <p> tab 1</p>
      </uib-tab>
      <uib-tab>
        <uib-tab-heading>
          Tab 2
        </uib-tab-heading>

        <p> tab 2</p>
      </uib-tab>
    </uib-tabset>

Vorlage: includeFile.html

<div>
  <span>This is for tesitng</span>
  <strong> <a href="www.google.com">www.google.com</a></strong>

</div>

html

 <span class="icon-globe" id="visibilityFor" popover="hello how are you" 
       popover-placement="right" popover-trigger="mouseenter" 
       popover-popup-delay="50" viz>
</span>

Richtlinie

myAppModule.directive('viz', function ($rootScope,$timeout){
    return{

        restrict:"A",
        link: function (scope, element, attrs) {
            $rootScope.insidePopover = false;

            element.bind('mouseenter', function (e) {
                $timeout(function () {
                    if (!$rootScope.insidePopover) {
                        element.popover('show');
                     //  attachEvents(element);
                    }
                }, 200);
            });

            element.bind('mouseout', function (e) {
                $timeout(function () {
                    if (!$rootScope.insidePopover) {
                        element.popover('show');
                     //   attachEvents(element);
                    }
                }, 200);
            });

        }
    }
});

Hinweis: - Vergessen Sie nicht, Schrägband nach jQuery.js & Winkel.js einzuschließen. 

0

Was ich in 0.13.X gemacht habe, ist, dass das Element als overcode auf <button> gesetzt wird und dann das popover-trigger = "focus" gesetzt wird. Dann gestalten Sie die Schaltfläche wie gewünscht und fokussieren Sie die Schaltfläche, indem Sie darauf klicken. Sie können im Popover schweben und auf einen Link klicken, alles was ich tun muss.

0
httpete