Ng-Bind-Html inside ng-repeat

青春壹個敷衍的年華 提交于 2019-12-12 02:39:59

问题


I'm making a custom autosuggest component where I hit a web service with a search term and it returns a list of suggestions which I display.

My issue is, I want to bold the matching term inside the list and angular is not playing nice with the extra html. I've seen countless and countless examples using ng-bind-html which I've gotten to work if I can bind to specific values, but not with a dynamic list of values.

This is my first angular project so I'm sure there is something simple I'm missing. The code I'm posting renders the html correctly but it only displays the last result multiple times (I understand why).

How can I accomplish what I'm trying to do?


Here is my jade code :

#search-main(ng-controller="autocomplete" data-api-url="/autocomplete.json")
  input(type="search" placeholder="Search" ng-model="termToComplete")
  input(type="image" name="submit" src="/search-icon.gif", alt="Submit")
  ul.autoSuggest(ng-if="items.length")
    li.fade-in(ng-repeat="item in items")
      h2: a(href="{{item.url}}" ng-bind-html="html")

Here is some of my js

app.filter('html', ['$sce', function ($sce) { 
  return function (text) {
    return $sce.trustAsHtml(text);
  };    
}])

app.controller('autocomplete', function($scope, $element, $timeout, acAPIservice, $location, $sce){
  $scope.items = [];
  $scope.apiUrl = $element.attr('data-api-url');
  $scope.termToComplete = undefined;

  $scope.showSuggestion = function(){
  var payload = {
    term : $scope.termToComplete
  }

  acAPIservice.getSearch($scope.apiUrl, payload)
    .success(function(data){
      $scope.items = $scope.items.concat(data.results);
      $scope.findMatch();

   })
    .error(function(data, status, headers, config){      
      $scope.items = [];
   });
  }

  //iterates over the results and bolds matching terms
  $scope.findMatch = function(){
    var term = $scope.termToComplete;
    angular.forEach($scope.items, function(value, key){
    $scope.items[key].title = $sce.trustAsHtml($scope.items[key].title.replace(new RegExp('(^|)(' + term + ')(|$)','ig'), '$1<b>$2</b>$3'));
    $scope.html = $scope.items[key].title;
      });
   }


  $scope.$watch('termToComplete', function(newValue, oldValue) {
    // reset everything
    $scope.items = [];
    $scope.start = 0;
    $scope.end = 0;
    $scope.total = 0;
    // if we still have a search term go get it
    if($scope.termToComplete){
      $scope.showSuggestion();
    }
  });
});

Here is my test-Json :

{
    "start" : 1,
    "end" : 8,
    "total" : 27,
    "results" : [{
        "id" : 0,
        "title" : "here is a title",
        "url" : "google.com"
    }, {
        "id" : 1,
        "title" : "here is another title",
        "url" : "google.com"
    }, {
        "id" : 2,
        "title" : "and another title",
        "url" : "google.com"
    }]
}

NOTE:

acAPIservice is just a factory that hits an API and returns the data


回答1:


You don't need to define $scope.html because you are already assigning the HTML to title.

You just need to use it right in your ng-repeat loop:

li.fade-in(ng-repeat="item in items")
  h2: a(ng-href="{{item.url}}" ng-bind-html="item.title")

I also recommend using ng-href instead of just href, because you are using an angular expression for the link ;)



来源:https://stackoverflow.com/questions/35464256/ng-bind-html-inside-ng-repeat

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!