3

I want ng-repeat to build the hrefs from the ui-srefs inside a string. FAQs are stored in a database with links in the text.

JSON

[
  {
    "question": "How do I find out about you?",
    "answer": "Go here "<a ui-sref='root.aboutUs'>about us"</a> page."
  }
]

Controller

(function() {
'use strict';

angular
    .module('test.faqs')
    .controller('Faqs', Faqs);

Faqs.$inject = ['faqService', 'exception', '$document', '$sce'];
/* @ngInject */
function Faqs(faqService, exception, $document, $sce) {
    var vm = this;
    vm.trustAsHtml = $sce.trustAsHtml;
    faqService.getFaqs()
        .then(function (response){
            vm.allFaqs = response;
        })
        .catch(function (){
            exception.catcher('Error retrieving faqs')(message);
        });
}
})();

HTML

<div id="faq_{{$index}}" ng-repeat="faq in faqs.allFaqs track by $index">
<div>
    <span ng-bind-html="faqs.trustAsHtml(faq.question)"></span>
</div>
<div>
    <span ng-bind-html="faqs.trustAsHtml(faq.answer)"></span>
</div>

PLUNKER

I'm looking for a way to process the ui-srefs coming from the json feed so the links work. Is there a way to do this?

Thanks in advance.

SOLVED

Directive

(function () {
'use strict';

angular
    .module('test')
    .directive('compileHtml', compileHtml);

/* @ngInject */
compileHtml.$inject = ['$compile', '$sce'];
function compileHtml($compile, $sce) {
    return {
        restrict: 'A',
        replace: true,
        link: function (scope, element, attrs) {
            var html = attrs.compileHtml;
            html = $sce.trustAsHtml(html);
            element.html(html);
            $compile(element.contents())(scope);
        }
    }
}
})();

Html

<div id="faq_{{$index}}" ng-repeat="faq in faqs.allFaqs track by $index">
    <div>
        <span compile-html="{{faq.question}}"></span>
    </div>
    <div>
        <span compile-html="{{faq.answer}}"></span>
    </div>
</div>

Thanks to goliney for pointing me in the right direction! Directive turns string into html and then compiles it back to the scope which makes the ui-srefs come to life.

Joe Keene
  • 2,175
  • 21
  • 27

1 Answers1

2

What you need is $compile service.

Updated PLUNKER

faqApp.controller('homeCtrl', function($scope, $sce, $compile) {
    $scope.test = "hello there!";
    $scope.allFaqs = [{
      "question": "Where can I get info about you?",
      "answer": $compile("<span>Go here: <a ui-sref='about'>about us</a><span>")($scope).html()
    }];
    $scope.trustAsHtml = $sce.trustAsHtml;
});
  1. Pass html to $compile. Note, that html has to have single root element.
  2. $compile() returns linking function, which can then be used to link $scope.
  3. Linked template can be injected in DOM. To make it work with the rest of your code I apply .html() to the linked template. But I would recomend to have a directive for that. Actually, if at some point you have to work with DOM - directives is a way to go. You may find this SO answer useful.
Community
  • 1
  • 1
Serhii Holinei
  • 5,758
  • 2
  • 32
  • 46