Twitter typeahead.js: Possible to use Angular JS as template engine? If not how do I replace "{{}}" for Hogan/Mustache js?

Ignore the documentation on this, just look at the source code:

function compileTemplate(template, engine, valueKey) {
    var renderFn, compiledTemplate;
    if (utils.isFunction(template)) {
        renderFn = template;
    } else if (utils.isString(template)) {
        compiledTemplate = engine.compile(template);
        renderFn = utils.bind(compiledTemplate.render, compiledTemplate);
    } else {
        renderFn = function(context) {
            return "<p>" + context[valueKey] + "</p>";
        };
    }
    return renderFn;
}

It happens you can just pass a function to template, callable with a context object which contains the data you passed in the datum objects at the time of instantiation, so:

$('#economists').typeahead({
  name: 'economists',
  local: [{
    value: 'mises',
    type: 'austrian economist',
    name: 'Ludwig von Mises'
  }, {
    value: 'keynes',
    type: 'keynesian economist',
    name: 'John Maynard Keynes'
  }],
  template: function (context) {
    return '<div>'+context.name+'<span>'+context.type.toUpperCase()+'</span></div>'
  }
})

If you want to use Hogan.js with Angular, you can change the delimiters by doing something like:

var text = "my <%example%> template."
Hogan.compile(text, {delimiters: '<% %>'});

It appears that the template engine result that typeahead.js expects is an html string and not the dom element (in dropdown_view.js). So I am not sure there is a good solution for using an angular template. As a test I was able to get it binding the result to an angular template but it has to render to an element and then get the html value from the element after binding with the data. I don't like this approach but I figured someone might find it useful. I think I will go with a template function like in the previous post.

Jade template looks like

.result
  p {{datum.tokens}}
  p {{datum.value}}

Directive

angular.module('app').directive('typeahead', [
  '$rootScope', '$compile', '$templateCache',
  function ($rootScope, $compile, $templateCache) {
    // get template from cache or you can load it from the server
    var template = $templateCache.get('templates/app/typeahead.html');
    var compileFn = $compile(template);
    var templateFn = function (datum) {
      var newScope = $rootScope.$new();
      newScope.datum = datum;
      var element = compileFn(newScope);
      newScope.$apply();
      var html = element.html();
      newScope.$destroy();
      return html;
    };
    return {
      restrict: 'A',
      link: function (scope, element, attrs, ctrl) {
        element.typeahead({
          name: 'server',
          remote: '/api/search?q=%QUERY',
          template: templateFn
        });
        element.on('$destroy', function () {
          element.typeahead('destroy');
        });
        element.on('typeahead:selected', function () {
          element.typeahead('setQuery', '');
        });
      }
    };
  }
]);