Ng-Bind-Html внутри ng-repeat

Я создаю собственный компонент автозаполнения, в котором я нажимаю на веб-службу с поисковым запросом, и он возвращает список предложений, которые я отображаю.

Моя проблема в том, что я хочу выделить соответствующий термин внутри списка, а angular не очень хорошо работает с дополнительным html. Я видел бесчисленное множество примеров использования ng-bind-html, которые я заработал, если бы мог привязываться к конкретным значениям, но не к динамическому списку значений.

Это мой первый угловой проект, поэтому я уверен, что мне не хватает чего-то простого. Код, который я публикую, правильно отображает html, но он отображает только последний результат несколько раз (я понимаю, почему).

Как я могу выполнить то, что я пытаюсь сделать?


Вот мой нефритовый код:

#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")

Вот некоторые из моих 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();
    }
  });
});

Вот мой тест-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"
    }]
}

ПРИМЕЧАНИЕ:

acAPIservice — это просто фабрика, которая обращается к API и возвращает данные


person Paidenwaffle    schedule 17.02.2016    source источник


Ответы (1)


Вам не нужно определять $scope.html, потому что вы уже назначаете HTML для title.

Вам просто нужно использовать его прямо в цикле ng-repeat:

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

Я также рекомендую использовать ng-href вместо href, потому что вы используете угловое выражение для ссылки;)

person Betty St    schedule 17.02.2016
comment
вау, большое спасибо, вы не представляете, сколько времени я потратил, пытаясь решить эту проблему. Вчера я попробовал это решение и, должно быть, не понял, что оно сработало... Ура, m8! - person Paidenwaffle; 17.02.2016