Using Bootstrap Tooltip with AngularJS

2020-02-02 04:04发布

I am trying to use the Bootstrap tooltip in an app of mine. My app is using AngularJS Currently, I have the following:

<button type="button" class="btn btn-default" 
        data-toggle="tooltip" data-placement="left"
        title="Tooltip on left">
            Tooltip on left
</button>

I think I need to use

$("[data-toggle=tooltip]").tooltip();

However, I'm not sure. Even when I add the line above though, my code doesn't work. I'm trying to avoid using UI bootstrap as it has more than I need. However, if I had to include just the tooltip piece, I'd be open to that. Yet, I can't figure out how to do that.

Can someone show me how to get the Bootstrap Tooltip working with AngularJS?

19条回答
何必那么认真
2楼-- · 2020-02-02 04:45

var app = angular.module('MyApp', ['mgcrea.ngStrap']);  
<link href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet">
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.15/angular.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-strap/2.1.2/angular-strap.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-strap/2.1.2/angular-strap.tpl.min.js"></script>

<div ng-app="MyApp" class="container" >

  <button type="button" 
          class="btn btn-default" 
          data-trigger="hover" 
          data-placement="right"
          data-title="Tooltip on right"
          bs-tooltip>
    MyButton
  </button>

</div>

查看更多
等我变得足够好
3楼-- · 2020-02-02 04:46

You can create a simple directive like this:

angular.module('myApp',[])
    .directive('myTooltip', function(){
        return {
            restrict: 'A',
            link: function(scope, element){
                element.tooltip();
            }
        }
    });

Then, add your custom directive where is necessary:

<button my-tooltip></button>
查看更多
不美不萌又怎样
4楼-- · 2020-02-02 04:48

Only read this if you are assigning tooltips dynamically

i.e. <div tooltip={{ obj.somePropertyThatMayChange }} ...></div>

I had an issue with dynamic tooltips that were not always updating with the view. For example, I was doing something like this:

This didn't work consistently

<div ng-repeat="person in people">
    <span data-toggle="tooltip" data-placement="top" title="{{ person.tooltip }}">
      {{ person.name }}
    </span> 
</div> 

And activating it as so:

$timeout(function() {
  $(document).tooltip({ selector: '[data-toggle="tooltip"]'});
}, 1500)

However, as my people array would change my tooltips wouldn't always update. I tried every fix in this thread and others with no luck. The glitch seemed to only be happening around 5% of the time, and was nearly impossible to repeat.

Unfortunately, these tooltips are mission critical for my project, and showing an incorrect tooltip could be very bad.

What seemed to be the issue

Bootstrap was copying the value of the title property to a new attribute, data-original-title and removing the title property (sometimes) when I would activate the toooltips. However, when my title={{ person.tooltip }} would change the new value would not always be updated into the property data-original-title. I tried deactivating the tooltips and reactivating them, destroying them, binding to this property directly... everything. However each of these either didn't work or created new issues; such as the title and data-original-title attributes both being removed and un-bound from my object.

What did work

Perhaps the most ugly code I've ever pushed, but it solved this small but substantial problem for me. I run this code each time the tooltip is update with new data:

$timeout(function() {
    $('[data-toggle="tooltip"]').each(function(index) {
      // sometimes the title is blank for no apparent reason. don't override in these cases.
      if ($(this).attr("title").length > 0) {
        $( this ).attr("data-original-title", $(this).attr("title"));
      }
    });
    $timeout(function() {
      // finally, activate the tooltips
      $(document).tooltip({ selector: '[data-toggle="tooltip"]'});
    }, 500);
}, 1500);

What's happening here in essence is:

  • Wait some time (1500 ms) for the digest cycle to complete, and the titles to be updated.
  • If there's a title property that is not empty (i.e. it has changed), copy it to the data-original-title property so it will be picked up by Bootstrap's toolips.
  • Reactivate the tooltips

Hope this long answer helps someone who may have been struggling as I was.

查看更多
我命由我不由天
5楼-- · 2020-02-02 04:50

If you're building an Angular app, you can use jQuery, but there is a lot of good reasons to try to avoid it in favor of more angular driven paradigms. You can continue to use the styles provided by bootstrap, but replace the jQuery plugins with native angular by using UI Bootstrap

Include the Boostrap CSS files, Angular.js, and ui.Bootstrap.js:

<link href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
<script src="https://code.angularjs.org/1.2.20/angular.js"></script>
<script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.11.0.js"></script>

Make sure you've injected ui.bootstrap when you create your module like this:

var app = angular.module('plunker', ['ui.bootstrap']);

Then you can use angular directives instead of data attributes picked up by jQuery:

<button type="button" class="btn btn-default" 
        title="Tooltip on left" data-toggle="tooltip" data-placement="left"
        tooltip="Tooltip on left" tooltip-placement="left" >
  Tooltip on left
</button>

Demo in Plunker


Avoiding UI Bootstrap

jQuery.min.js (94kb) + Bootstrap.min.js (32kb) is also giving you more than you need, and much more than ui-bootstrap.min.js (41kb).

And time spent downloading the modules is only one aspect of performance.

If you really wanted to only load the modules you needed, you can "Create a Build" and choose tooltips from the Bootstrap-UI website. Or you can explore the source code for tooltips and pick out what you need.

Here a minified custom build with just the tooltips and templates (6kb)

查看更多
6楼-- · 2020-02-02 04:52

Have you included the Bootstrap JS and jQuery?

<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script src="//netdna.bootstrapcdn.com/bootstrap/3.0.2/js/bootstrap.min.js"></script>

If you don't already load those, then Angular UI (http://angular-ui.github.io/bootstrap/) may not be much overhead. I use that with my Angular app, and it has a Tooltip directive. Try using tooltip="tiptext"

<button type="button" class="btn btn-default" 
        data-toggle="tooltip" data-placement="left"
        title="Tooltip on left"
        tooltip="This is a Bootstrap tooltip"
        tooltip-placement="left" >
            Tooltip on left
</button>
查看更多
淡お忘
7楼-- · 2020-02-02 04:52

You can do this with AngularStrap which

is a set of native directives that enables seamless integration of Bootstrap 3.0+ into your AngularJS 1.2+ app."

You can inject the entire library like this:

var app = angular.module('MyApp', ['mgcrea.ngStrap']); 

Or only pull in the tooltip feature like this:

var app = angular.module('MyApp', ['mgcrea.ngStrap.tooltip']); 

Demo in Stack Snippets

var app = angular.module('MyApp', ['mgcrea.ngStrap']);  
<link href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet">
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.15/angular.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-strap/2.1.2/angular-strap.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-strap/2.1.2/angular-strap.tpl.min.js"></script>

<div ng-app="MyApp" class="container" >

  <button type="button" 
          class="btn btn-default" 
          data-trigger="hover" 
          data-placement="right"
          data-title="Tooltip on right"
          bs-tooltip>
    MyButton
  </button>

</div>

查看更多
登录 后发表回答