1

我一生都无法弄清楚如何让角带弹出框在返回的 JSON 内容中工作(数据属性在 JSON 文件中)。

Plunkr:http ://plnkr.co/edit/jVmHwIwJ0KOKCnX6QjVa?p=preview

任何见解将不胜感激。非常感谢!

HTML

<!-- Search -->
<div class="well"> 
  <p>Search the term "content"</p>
  <form role="form">
    <div my-search ng-model="selectedContent" class="form-group clearfix search">
      <input type="text" ng-model="selectedContent" ng-options="query as query.searchQuery for query in searchData" bs-typeahead="bs-typeahead" class="form-control search-field"/>
      <button type="button" class="btn btn-primary search-btn" ng-click="updateModel()"><span class="glyphicon glyphicon-search"></span></button>
    </div>
  </form>
</div>

<!-- Dynamic Content -->
<div class="well">
  <h4>{{clickedContent.contentTitle}}</h4>
  <ul>
    <li ng-repeat="item in clickedContent.headlines" ng-bind-html="item.headline"></li>
  </ul>
</div>

JSON

      [
        {
            "contentId": 1,
            "searchQuery": "Content set 1 dummy query vestibulum abcdefghijklmnop",
            "contentTitle": "Pretaining to content set 1",
            "popoverTitle": "Query info",
            "popoverContent": "Interesting info about query",
            "headlines": [
                {
                  "headline": "<a href='#' data-placement='bottom', data-trigger='hover' data-title='Headline details' data-content='details about headline' bs-popover>1st headline in content set 1</a>"
                },
                {
                  "headline": "<a href='#' data-placement='bottom', data-trigger='hover' data-title='Headline details' data-content='details about headline' bs-popover>2nd headline in content set 1</a>"
                },
                {
                  "headline": "<a href='#' data-placement='bottom', data-trigger='hover' data-title='Headline details' data-content='details about headline' bs-popover>3rd headline in content set 1</a>"
                }
            ]

        },
        {
            "contentId": 2,
            "searchQuery": "Content set 2 dummy query vestibulum abcdefghijklmnop",
            "contentTitle": "Pretaining to content set 2",
            "popoverTitle": "Query info",
            "popoverContent": "Interesting info about query",
            "headlines": [
                {
                  "headline": "<a href='#' data-placement='bottom', data-trigger='hover' data-title='Headline details' data-content='details about headline' bs-popover>1st headline in content set 2</a>"
                },
                {
                  "headline": "<a href='#' data-placement='bottom', data-trigger='hover' data-title='Headline details' data-content='details about headline' bs-popover>2nd headline in content set 2<a/>"
                },
                {
                  "headline": "<a href='#' data-placement='bottom', data-trigger='hover' data-title='Headline details' data-content='details about headline' bs-popover>3rd headline in content set 2</a>"
                }
            ]
        },
        {
            "contentId": 3,
            "searchQuery": "Content set 3 dummy query vestibulum abcdefghijklmnop",
            "contentTitle": "Pretaining to content set 3",
            "popoverTitle": "Query info",
            "popoverContent": "Interesting info about query",
            "headlines": [
                {
                  "headline": "<a href='#' data-placement='bottom', data-trigger='hover' data-title='Headline details' data-content='details about headline' bs-popover>1st headline in content set 3</a>"
                },
                {
                  "headline": "<a href='#' data-placement='bottom', data-trigger='hover' data-title='Headline details' data-content='details about headline' bs-popover>2nd headline in content set 3</a>"
                },
                {
                  "headline": "<a href='#' data-placement='bottom', data-trigger='hover' data-title='Headline details' data-content='details about headline' bs-popover>3rd headline in content set 3</a>"
                }
            ]
        },
            {
            "contentId": 4,
            "searchQuery": "Content set 4 dummy query vestibulum abcdefghijklmnop",
            "contentTitle": "Pretaining to content set 4",
            "popoverTitle": "Query info",
            "popoverContent": "Interesting info about query",
            "headlines": [
                {
                  "headline": "<a href='#' data-placement='bottom', data-trigger='hover' data-title='Headline details' data-content='details about headline' bs-popover>1st headline in content set 4</a>"
                },
                {
                  "headline": "<a href='#' data-placement='bottom', data-trigger='hover' data-title='Headline details' data-content='details about headline' bs-popover>2nd headline in content set 4</a>"
                },
                {
                  "headline": "<a href='#' data-placement='bottom', data-trigger='hover' data-title='Headline details' data-content='details about headline' bs-popover>3rd headline in content set 4</a>"
                }
            ]
        }
    ]

JS

            var app = angular.module('demoApp', ['ngAnimate', 'ngSanitize', 'mgcrea.ngStrap'])
            .config(function ($typeaheadProvider) {
              angular.extend($typeaheadProvider.defaults, {
                template: 'ngstrapTypeahead.html',
                container: 'body'
              }); 
            });

            app.directive('mySearch', function(){
              return {
                restrict: 'A',
                require: 'ngModel',
                link: function($scope, $element, $attrs, ngModel){
                  ngModel.$render = function(){
                     if (angular.isObject($scope.selectedContent)) {
                       $scope.clickedContent = $scope.selectedContent;
                     }
                  }
                   $scope.updateModel = function() {
                     $scope.clickedContent = $scope.selectedContent;
                  }
                }
              }

            })

            function MainController($scope, $templateCache, $http) {

              $scope.selectedContent = '';

              $http.get('searchData.json').then(function(response){
                $scope.searchData = response.data;
                return $scope.searchData;
              });

            };
4

2 回答 2

1

我想这就是你想要的。如果是这样,不客气:)

工作示例

基本上我做了两件事。我不喜欢将数据发送到 unsafe-html 的函数,更好的方法是通过它进行过滤器和管道日期.. 更好,因为您可以内联而不将它们发送到函数。我在您的 app.js 中将此过滤器称为“不安全”

app.filter('unsafe', function($sce) {
    return function(val) {
      return $sce.trustAsHtml(val);
    };
});

其次..就像上面在评论中提到的那样,仅仅因为您可以“渲染”它并不意味着它已被编译..因此您必须运行编译指令来重新处理渲染的 HTML 并将其转换为我们关心的代码。我称该指令为“编译模板”

app.directive('compileTemplate', function($compile, $parse){
 return {
link: function(scope, element, attr){
  var parsed = $parse(attr.ngBindHtml);
  function getStringValue() { return (parsed(scope) || '').toString(); }

        //Recompile if the template changes
        scope.$watch(getStringValue, function() {
            $compile(element, null, -9999)(scope);  //The -9999 makes it skip directives so that we do not recompile ourselves
          });
      }         
    }
  });

你会这样写你的“动态内容”:

    <!-- Dynamic Content -->
<div class="well">
  <h4>{{clickedContent.contentTitle}}</h4>
  <ul>
    <li ng-repeat="item in clickedContent.headlines" ng-bind-html="item.headline | unsafe" compile-template></li>
  </ul>
</div>

现在您可以看到该示例有效。

如果这有帮助,请给代表!谢谢!!!

于 2014-06-20T21:07:05.227 回答
0

您面临的问题是 AngularJS,为了您客户的安全,会自动清理ng-bind-html属性中的 HTML 输入。它会自动删除任何潜在的恶意属性,例如 JS 事件、数据前缀属性、id属性(可能是为了防止冲突......)和style.

该文档显示了如何绕过此自动清理。

在本质上:

  1. $scope在您的MainController.
  2. 用于$templateCache.trustAsHtml(<html>)返回原始 HTML。
  3. 在属性中调用该函数ng-bind-html来检索原始 HTML。

不幸的是,我对 AngularJS 不是很有经验,并且无法在您的示例中使用它。(我不知道如何将一个或多或少的动态变量传递给函数,我曾希望ng-bind-html=\"rawHtml(item.headline)\"会足够好,但事实并非如此。)

祝你好运!

于 2014-06-18T08:48:41.840 回答