Angularjs 没有为 Bootstrap 弹出窗口插入标题

Angularjs not interpolating title for Bootstrap Popover

我正在尝试在 AngularJS ngRepeat 指令中使用 Bootstrap 弹出窗口。问题是 title 属性没有被插入。我该如何解决这个问题?

查看

<div ng-app="app" id="ng-app">
<ul ng-controller="Main">
    <li ng-repeat="i in items" data-toggle="popover" title="{{ i.title }}" <!-- Title isn't interpolated so Popover doesn't render a title -->
        data-content="Events: {{ day.events.length }}"
        init-popover>{{ i.data }}</li>
</ul>

代码

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

app.controller('Main', ['$scope', function($scope){
    $scope.items = [
        { title: 'Title 1', data: 'lorem' },
        { title: 'Title 2', data: 'ipsum' },
    ];
}]);

app.directive('initPopover', function() {
  return function(scope, element, attrs) {
    if (scope.$last){
      $('[data-toggle="popover"]').popover({container: 'ul'});
    }
  };
});

FIDDLE

你不应该使用 title="{{i.title}}",但是 ng-attr-title="{{i.title}}"...

考虑将 ui-bootstrap 用于本机 Angular 指令,而不是 Bootstrap 的 jQuery 版本。在 Angular 项目中使用它们要容易得多。

编辑: 如果您不能这样做,这里有一个解决方案:

<li ng-repeat="i in items" data-toggle="popover" data-ng-attr-popover_title="{{ i.title }}" 
            data-content="Popover Content"
            init-popover>{{ i.data }}</li>

对指令稍作更改:

app.directive('initPopover', function() {
  return function(scope, element, attrs) {
    if (scope.$last){
        $('[data-toggle="popover"]').popover({ container: 'ul', title: attrs.popoverTitle });
    }
  };

ng-attr-popup_title 将在元素上创建一个名为 popupTitle 的 HTML 属性,{{}} 中的 Angular 语法已正确解析。然后,在指令中,我们可以检查该属性来设置弹出窗口标题。

Fiddle: here

在指令中添加 $timeout 将解决您的问题。 当 ng-repeat 的最后一个元素在 UI & 运行 $digest 循环中呈现时,$timeout 将被调用。

指令

app.directive('initPopover', function($timeout) {
    return function(scope, element, attrs) {
        if (scope.$last) {
            $timeout(function() {
                angular.element('[data-toggle="popover"]').popover({
                    container: 'ul'
                });
            });
        }
    };
});

Working Fiddle

希望对您有所帮助。谢谢

你可以让它工作,但它很丑,这是我的解决方案

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

app.controller('Main', ['$scope', function($scope){
    $scope.items = [        
        { title: 'Title 1', data: 'Test in ngRepeat' },
        { title: 'Title 2', data: 'Test in ngRepeat' },
    ];
}]);

app.directive('initPopover', function() {
  return function(scope, element, attrs) {
      if (scope.$last) {
      attrs.$observe('title', function () {
          $('[data-toggle="popover"]').popover({container: 'ul'});
      });
      }
  };
});

只是为了添加到这里的知识库。这是 angular 方式,以备不时之需。我的解决方案基于 Mark Coleman's PopOver tutorial,当然还有 Nate Barbettini 贡献的内容。

我的情况是我有一个嵌套的 ng-repeat over items in items,所以我需要一个基于存储在范围中的数组的弹出窗口的标题,而弹出窗口的内容是来自存储在范围数组中的另一个数组。

我将 ng-attr-title 添加到我的 HTML 元素中,如下所示:

 <div pop-over items='week.items' ng-attr-title="{{'Week number:'+ week.week}}">  Total sales this week : {{week.sales}}</div>

然后,在我的指令中,我主要遵循了 Mark Coleman 所做的。

    angular.module('vegadirectives', [])
.directive('popOver', function ($compile, $templateCache) {

var itemsTemplate = "<ul class='popper'><li ng-repeat='thing in items track by $index'>";
itemsTemplate+=" <i class='fa fa-square' ng-class=";
itemsTemplate+="{purple:thing.color==='purple','orange':thing.color==='orange','white':thing.color==='white','pink':thing.color==='pink','red':thing.color==='red','green':thing.color==='green','yellow':thing.color==='yellow'}";
itemsTemplate+="></i>  {{thing.model}} - {{thing.qty}}</li></ul>";
    var getTemplate = function () {
        var template=itemsTemplate;
        return template;
    }
    return {
        restrict: "A",
        transclude: true, 
        template: "<span ng-transclude></span>",
        link: function (scope, element, attrs) {
            var popOverContent;


            if (scope.items) {
                var html = getTemplate();
                popOverContent = $compile(html)(scope);                    
                var options = {
                    trigger:'click',
                    content: popOverContent,
                    placement: "right",
                    html: true,
                    title:scope.title


                };
                if (scope.$last) {

                }
                $(element).popover(options);
            }
        },
        scope: {
            items: '=',
           title:'@'
        }
    };
});

解释:

为了用项目列表填充我的弹出窗口,用一些花哨的颜色方块来指示不同类型的项目,我创建了一大块 HTML 代码。 $compile 将使用这个名为 itemsTemplate 的块来创建具有范围的弹出内容。我认为用法是 $compile(htmlstring)(scope).

接下来是弹出框选项设置的标准内容。 对于带标题的范围插值,我指定了选项 title:scope.title。然后,在最后的 scope: 选项中,两个范围元素用 '=''@' 指定。

所以,title:scope.title引用或绑定scope: {items:'=', title:'@' },而title:'@'是HTML中标题的属性,即ng-attrs-title={{week.week}},其中周来自外部 ng-repeat 循环。

希望对您有所帮助。

在 找到这个答案后,我尝试了 data-original-title={{i.title}},它有效。

http://jsfiddle.net/f1tjj8x5/

<li ng-repeat="i in items" data-toggle="popover" data-original-title="{{ i.title }}" 
        data-content="Popover Content"
        init-popover>{{ i.data }}</li>

我遇到了同样的问题。我正在使用 bootstrap v3.3.6 和 Angular v1.5.0

添加属性 data-original-title="{{someTitle}}" 解决了问题。

<button type="button" class="btn btn-lg btn-danger" data-toggle="popover" title="{{someTitle}}" data-original-title="{{someTitle}}" data-content="Some Content">Click to toggle popover</button>

另外,根据bootstrap的要求,在指令

中调用.popover()
module.directive('myDir', ['jQuery', function (jQuery) {
    return {
        link: function () {
            jQuery('[data-toggle="popover"]').popover();
        }
    };
}]);