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

StackOverflow https://stackoverflow.com/questions/17904384

I am working with twitter's typeahead.js and I was wondering if it was possible to modify hogan.js to use something other than {{}}?

I am looking at the minified code now and I have no idea what to change for something so simple. Doing a find and replace breaks it.

I am asking this mainly because I'm using Angular JS but twitter's typeahead requires a templating engine, causing hogan and angular's {{}} to clash. An even better solution would be simply modifying Angular JS (I know it's not a templating engine) and ditching Hogan to fit the following criteria:

Any template engine will work with typeahead.js as long as it adheres to the following API:

// engine has a compile function that returns a compiled template
var compiledTemplate = ENGINE.compile(template);

// compiled template has a render function that returns the rendered template
// render function expects the context to be first argument passed to it
var html = compiledTemplate.render(context);
有帮助吗?

解决方案 2

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: '<% %>'});

其他提示

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>'
  }
})

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', '');
        });
      }
    };
  }
]);
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top