7

我正在使用twitter 的 typeahead.js,我想知道是否可以修改hogan.js为使用除{{}}.

我现在正在查看缩小的代码,但我不知道要为这么简单的东西更改什么。进行查找和替换会破坏它。

我问这个主要是因为我使用的是 Angular JS,但是 twitter 的 typeahead 需要一个模板引擎,导致 hogan 和 angular 的{{}}冲突。一个更好的解决方案是简单地修改 Angular JS(我知道它不是模板引擎)并放弃 Hogan 以符合以下标准:

只要遵循以下 API,任何模板引擎都可以使用 typeahead.js:

// 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);
4

3 回答 3

14

忽略这方面的文档,只看源代码

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;
}

碰巧您可以将一个函数传递给template,该函数可使用一个对象调用,该context对象包含您在实例化时传入数据对象的数据,因此:

$('#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>'
  }
})
于 2013-09-03T22:52:56.637 回答
3

如果您想将 Hogan.js 与 Angular 一起使用,您可以通过执行以下操作来更改分隔符:

var text = "my <%example%> template."
Hogan.compile(text, {delimiters: '<% %>'});
于 2013-07-29T19:46:21.093 回答
3

typeahead.js 期望的模板引擎结果似乎是 html 字符串,而不是 dom 元素(在 dropdown_view.js 中)。所以我不确定使用角度模板是否有一个好的解决方案。作为测试,我能够将结果绑定到角度模板,但它必须渲染到元素,然后在与数据绑定后从元素中获取 html 值。我不喜欢这种方法,但我想有人可能会觉得它有用。我想我会像上一篇文章那样使用模板函数。

玉模板看起来像

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

指示

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', '');
        });
      }
    };
  }
]);
于 2013-09-26T22:25:50.793 回答