Хороший способ динамически открывать / закрывать popover (или всплывающую подсказку), используя угловой, основанный на выражении?

У меня есть форма, которая подключена к угловому, используя ее для проверки. Я могу отображать сообщения об ошибках с помощью ng-show-директив:

  This field is required.   

.. где f – форма, а t3 – пользовательская директива по форме, которая определяет, была ли попытка отправки, и содержит функции для проверки действительности полей.

То, что я пытаюсь выполнить, – это отображать сообщения (ы) проверки в popover вместо этого. Либо загрузочный файл bootstrap, либо popover из UI Bootstrap , я загрузил оба. Я также могу рассмотреть AngularStrap, если это проще сделать с помощью этой библиотеки.

То, с чем я сейчас сталкиваюсь, – это природа popovers в целом – они автоматически отображаются на основе пользовательских событий, таких как щелчок, мыши, размытие и т. Д. Что я хочу сделать, это показать и скрыть popover (s) на основе того же функции в атрибутах ng-show выше. Таким образом, когда выражение возвращает false, скройте его, и когда оно вернет true, покажите его.

Я знаю, что bootstrap имеет .popover (‘show’) для этого, но я не должен сообщать угловое что-либо о dom, поэтому я не уверен, как получить доступ к $ (element) .popover () if делая это в пользовательской форме controllerа. Я что-то упускаю?

Обновить

Решение, упомянутое в повторном голосовании, по-прежнему показывает только popover на mouseenter. Я хочу заставить его отображать, как будто делает $('#popover_id').popover('show') .

Вы также можете создавать собственные расширенные триггеры. Это применимо как к Tooltip, так и к Popover.

Сначала распространите триггеры Tooltip следующим образом:

 // define additional triggers on Tooltip and Popover app.config(['$tooltipProvider', function($tooltipProvider){ $tooltipProvider.setTriggers({ 'show': 'hide' }); }]); 

Затем определите триггер в теге HTML следующим образом:

 

И теперь вы можете вызвать hide и show из JavaScript, это шоу за 3 секунды.

 $("#RegisterHelp").trigger('show'); //Close the info again $timeout(function () { $("#RegisterHelp").trigger('hide'); }, 3000); 

Как оказалось, не очень сложно украсить подсказку ui-bootstrap или popover с помощью специальной директивы. Это написано в машинописном тексте, но части его javascript должны быть очевидны. Эта отдельная часть кода работает, чтобы украсить либо всплывающую подсказку, либо popover:

 'use strict'; module App.Directives.TooltipToggle { export interface DirectiveSettings { directiveName: string; directive: any[]; directiveConfig?: any[]; } export function directiveSettings(tooltipOrPopover = 'tooltip'): DirectiveSettings { var directiveName = tooltipOrPopover; // events to handle show & hide of the tooltip or popover var showEvent = 'show-' + directiveName; var hideEvent = 'hide-' + directiveName; // set up custom triggers var directiveConfig = ['$tooltipProvider', ($tooltipProvider: ng.ui.bootstrap.ITooltipProvider): void => { var trigger = {}; trigger[showEvent] = hideEvent; $tooltipProvider.setTriggers(trigger); }]; var directiveFactory = (): any[] => { return ['$timeout', ($timeout: ng.ITimeoutService): ng.IDirective => { var d: ng.IDirective = { name: directiveName, restrict: 'A', link: (scope: ng.IScope, element: JQuery, attr: ng.IAttributes) => { if (angular.isUndefined(attr[directiveName + 'Toggle'])) return; // set the trigger to the custom show trigger attr[directiveName + 'Trigger'] = showEvent; // redraw the popover when responsive UI moves its source var redrawPromise: ng.IPromise; $(window).on('resize', (): void => { if (redrawPromise) $timeout.cancel(redrawPromise); redrawPromise = $timeout((): void => { if (!scope['tt_isOpen']) return; element.triggerHandler(hideEvent); element.triggerHandler(showEvent); }, 100); }); scope.$watch(attr[directiveName + 'Toggle'], (value: boolean): void => { if (value && !scope['tt_isOpen']) { // tooltip provider will call scope.$apply, so need to get out of this digest cycle first $timeout((): void => { element.triggerHandler(showEvent); }); } else if (!value && scope['tt_isOpen']) { $timeout((): void => { element.triggerHandler(hideEvent); }); } }); } }; return d; }]; }; var directive = directiveFactory(); var directiveSettings: DirectiveSettings = { directiveName: directiveName, directive: directive, directiveConfig: directiveConfig, }; return directiveSettings; } } 

С помощью этого единственного fragmentа кода вы можете настроить программную прямую и показать либо всплывающую подсказку, либо popover:

 var tooltipToggle = App.Directives.TooltipToggle.directiveSettings(); var popoverToggle = App.Directives.TooltipToggle.directiveSettings('popover'); var myModule = angular.module('my-mod', ['ui.bootstrap.popover', 'ui.bootstrap.tpls']) .directive(tooltipToggle.directiveName, tooltipToggle.directive) .config(tooltipToggle.directiveConfig) .directive(popoverToggle.directiveName, popoverToggle.directive) .config(popoverToggle.directiveConfig); 

Применение:

  

или

  

Таким образом, мы повторно используем все, что связано с подсказкой ui-bootstrap или popover, и только реализуем атрибут -toggle . Декоративная директива наблюдает за атрибутом и запускает пользовательские события для отображения или скрытия, которые затем обрабатываются провайдером подсказок ui-bootstrap.

Обновить:

Поскольку этот ответ, похоже, помогает другим, вот код, написанный как javascript (вышеупомянутый машинописный текст более или менее компилируется на этот javascript):

 'use strict'; function directiveSettings(tooltipOrPopover) { if (typeof tooltipOrPopover === "undefined") { tooltipOrPopover = 'tooltip'; } var directiveName = tooltipOrPopover; // events to handle show & hide of the tooltip or popover var showEvent = 'show-' + directiveName; var hideEvent = 'hide-' + directiveName; // set up custom triggers var directiveConfig = ['$tooltipProvider', function ($tooltipProvider) { var trigger = {}; trigger[showEvent] = hideEvent; $tooltipProvider.setTriggers(trigger); }]; var directiveFactory = function() { return ['$timeout', function($timeout) { var d = { name: directiveName, restrict: 'A', link: function(scope, element, attr) { if (angular.isUndefined(attr[directiveName + 'Toggle'])) return; // set the trigger to the custom show trigger attr[directiveName + 'Trigger'] = showEvent; // redraw the popover when responsive UI moves its source var redrawPromise; $(window).on('resize', function() { if (redrawPromise) $timeout.cancel(redrawPromise); redrawPromise = $timeout(function() { if (!scope['tt_isOpen']) return; element.triggerHandler(hideEvent); element.triggerHandler(showEvent); }, 100); }); scope.$watch(attr[directiveName + 'Toggle'], function(value) { if (value && !scope['tt_isOpen']) { // tooltip provider will call scope.$apply, so need to get out of this digest cycle first $timeout(function() { element.triggerHandler(showEvent); }); } else if (!value && scope['tt_isOpen']) { $timeout(function() { element.triggerHandler(hideEvent); }); } }); } }; return d; }]; }; var directive = directiveFactory(); var directiveSettings = { directiveName: directiveName, directive: directive, directiveConfig: directiveConfig, }; return directiveSettings; } 

Для ui.bootstrap 0.13.4 и новее:

Был popover-is-open новый параметр ( popover-is-open ) для управления popovers в официальном ui.bootstrap . Так вы используете его в последней версии:

  Click me to show the popover!  

Для ui.bootstrap 0.13.3 и старше:

Я только что опубликовал небольшую директиву, которая добавляет больше контроля над popovers на GitHub:
https://github.com/Elijen/angular-popover-toggle

Вы можете использовать переменную области видимости для отображения / скрытия popover с помощью popover-toggle="variable" следующим образом:

  Popover here  

Вот демо Plunkr:
http://plnkr.co/edit/QeQqqEJAu1dCuDtSvomD?p=preview

Мой подход:

  • Отслеживать состояние popover в модели
  • Измените это состояние на элемент с помощью соответствующих директив.

Идея состоит в том, чтобы оставить DOM-манипуляцию директивам.

Я собрал скрипку, которая, надеюсь, даст лучшее объяснение, но вы найдете гораздо более сложные решения в UI Bootstrap, о которых вы упомянули.

jsfiddle

Разметка:

 
Popover
{{ element.name }}

JS:

 function DemoCtrl($scope) { $scope.elements = [ {name: 'Element1 (Error)', error: true, hovered: false}, {name: 'Element2 (no error)', error: false, hovered: false}, {name: 'Element3 (Error)', error: true, hovered: false}, {name: 'Element4 (no error)', error: false, hovered: false}, {name: 'Element5 (Error)', error: true, hovered: false}, ]; $scope.popoverShow = function(element) { element.hovered = true; } $scope.popoverHide = function(element) { element.hovered = false } } 

От ответа Майкла Штрамеля, но с полным угловым решением:

 // define additional triggers on Tooltip and Popover app.config(['$tooltipProvider', function($tooltipProvider){ $tooltipProvider.setTriggers({ 'show': 'hide' }); }]) 

Теперь добавьте эту директиву:

 app.directive('ntTriggerIf', ['$timeout', function ($timeout) { /* Intended use: 
*/ return { restrict: 'A', link: function (scope, element, attrs) { attrs.$observe('ntTriggerIf', function (val) { try { var ob_options = JSON.parse(attrs.ntTriggerIf.split("'").join('"') || ""); } catch (e) { return } $timeout(function () { for (var st_name in ob_options) { var condition = ob_options[st_name]; if (condition) { element.trigger(st_name); } } }) }) } } }])

Затем в вашей разметке:

  

Для других, приезжающих сюда, начиная с версии 0.13.4, мы добавили возможность программно открывать и закрывать popovers через атрибут *-is-open как для всплывающих подсказок, так и для popovers в библиотеке Angular UI Bootstrap. Таким образом, больше нет причин отказываться от собственного кода / решения.

Давайте будем гением компьютера.