28

検証に使用して、角度に配線されたフォームがあります。次のように ng-show ディレクティブを使用してエラー メッセージを表示できます。

<span ng-show="t3.f.needsAttention(f.fieldName)" ng-cloak>
    <span ng-show="f.fieldName.$error.required && !f.fieldName.$viewValue">
        This field is required.
    </span>
</span>

..fはフォームでt3、送信が試行されたかどうかを検出するフォームのカスタム ディレクティブから取得され、フィールドの有効性をチェックする関数が含まれています。

私が達成しようとしているのは、代わりにポップオーバー内に検証メッセージを表示することです。ブートストラップのネイティブ ポップオーバー、またはUI Bootstrapのポップオーバーのいずれかをロードしました。そのライブラリを使用する方が簡単な場合は、AngularStrap を検討することもできます。

私が今苦労しているのは、一般的なポップオーバーの性質です-クリック、マウス入力、ぼかしなどのユーザーイベントに基づいて自動表示されます。私がやりたいのは、同じに基づいてポップオーバーを表示および非表示にすることです上記の ng-show 属性の関数。式が false を返したときに非表示にし、true を返したときに表示するようにします。

ブートストラップにはこのための .popover('show') があることは知っていますが、Angular に dom について何も伝えてはいけません。カスタムフォームコントローラー関数でこれを行います。何か不足していますか?

アップデート

重複投票で言及されている解決策では、マウスエンターのポップオーバーのみが表示されます。のように強制的に表示させたい$('#popover_id').popover('show')

4

6 に答える 6

29

独自の拡張トリガーを作成することもできます。これは、ツールチップとポップオーバーの両方に適用されます。

まず、Tooltip トリガーを次のように拡張します。

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

次に、次のように HTML タグでトリガーを定義します。

<div id="RegisterHelp" popover-trigger="show" popover-placement="left" popover="{{ 'Login or register here'}}">

そして、JavaScript から hide と show を呼び出すことができるようになりました。これは 3 秒で表示されます。

$("#RegisterHelp").trigger('show');
//Close the info again
$timeout(function () {
    $("#RegisterHelp").trigger('hide');
}, 3000);
于 2014-04-30T00:08:19.160 に答える
20

結局のところ、カスタム ディレクティブを使用して ui-bootstrap ツールチップまたはポップオーバーを装飾することはそれほど難しくありません。これは typescript で書かれていますが、javascript の部分は明らかなはずです。この 1 つのコードは、ツールチップまたはポップオーバーのいずれかを装飾するために機能します。

'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<void>;
                        $(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;
    }
}

この 1 つのコードで、次のように、ツールチップまたはポップオーバーのプログラムによる非表示と表示を設定できます。

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);

使用法:

<span tooltip="This field is required."
    tooltip-toggle="formName.fieldName.$error.required"
    tooltip-animation="false" tooltip-placement="right"></span>

また

<span popover="This field is required."
    popover-toggle="formName.fieldName.$error.required"
    popover-animation="false" popover-placement="right"></span>

そのため、ui-bootstrap ツールチップまたはポップオーバーに付属する他のすべてを再利用し、-toggle属性のみを実装しています。装飾ディレクティブはその属性を監視し、カスタム イベントを起動して表示または非表示にします。これは、ui-bootstrap ツールチップ プロバイダーによって処理されます。

アップデート:

この答えは他の人を助けているように見えるので、ここにjavascriptとして書かれたコードがあります(上記のtypescriptは多かれ少なかれこの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;
}
于 2014-01-06T15:11:08.833 に答える
17

ui.bootstrap0.13.4 以降の場合:

popover-is-open公式リポジトリでポップオーバーを制御するための新しいパラメーター ( ) が導入されましたui.bootstrap。これは、最新バージョンでの使用方法です。

<a uib-popover="Hello world!" popover-is-open="isOpen" ng-click="isOpen = !isOpen">
   Click me to show the popover!
</a>

ui.bootstrap0.13.3 以前の場合:

GitHub でポップオーバーの制御を追加する小さなディレクティブを公開しました:
https://github.com/Elijen/angular-popover-toggle

popover-toggle="variable"次のようなディレクティブを使用して、スコープ変数を使用してポップオーバーを表示/非表示にすることができます。

<span popover="Hello world!" popover-toggle="isOpen">
   Popover here
</span>

Plunkr のデモはこちら:
http://plnkr.co/edit/QeQqqEJAu1dCuDtSvomD?p=preview

于 2015-07-12T20:55:02.530 に答える
3

Michael Stramel の回答から、ただし完全な angularJS ソリューションを使用:

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

次のディレクティブを追加します。

app.directive('ntTriggerIf', ['$timeout',
function ($timeout) {
    /*
    Intended use:
        <div nt-trigger-if={ 'triggerName':{{someCodition === SomeValue}},'anotherTriggerName':{{someOtherCodition === someOtherValue}} } ></div>
    */
    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);
                        }
                    }
                })

            })
        }
    }
}])

次に、マークアップで:

<span tooltip-trigger="show" tooltip="Login or register here" nt-trigger-if="{'show':{{ (errorConidtion) }}, 'hide':{{ !(errorConidtion) }} }"></span>
于 2015-09-18T21:36:30.430 に答える