Handlebars:TypeError:无法读取属性' helperMissing'未定义的

时间:2016-02-14 18:56:28

标签: javascript templates gulp handlebars.js precompiled-templates

我遇到了Handlebars编译模板的问题。我觉得我完全错过了一些重要的东西,但我尽可能地尝试,我似乎无法解决这个问题,或者在网上找到任何有关这种特殊情况出现的信息。

我正在使用gulp-handlebars使用Gulp任务进行编译。 gulp的任务是:

gulp.task('build-hbs', function(){
  gulp.src('root/app/src/hbs/*.hbs')
  .pipe(handlebars())
  .on('error', notify.onError({
    message: 'Error: <%= error.message %>'
  }))
  .pipe(declare({
    namespace: 'Handlebars.templates',
    noRedeclare: true // Avoid duplicate declarations
  }))
  .pipe(concat('templates.js'))
  .pipe(gulp.dest('root/app/js/templates/'));
});

对于简单的模板,一切正常,但我现在正在尝试使用一个简单的帮助器(注意:使用非编译模板时,帮助程序工作正常)。帮手是:

Handlebars.registerHelper('gravatar', function(hash, size) {
  var grav = '<img src="http://www.gravatar.com/avatar/' + hash + '.jpg?r=g&d=mm&s=' + size + '">';
  return new Handlebars.SafeString(grav);
});

模板本身如下所示:

<div id="nick"><b>{{display}}</b></div>
<div id="image">{{gravatar hash}}</div>

编译完成后,我得到:

this["Handlebars"] = this["Handlebars"] || {};
this["Handlebars"]["templates"] = this["Handlebars"]["templates"] || {};
this["Handlebars"]["templates"]["profile"] = {"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
    var helper, alias1=helpers.helperMissing, alias2="function", alias3=this.escapeExpression;

  return "<div id=\"nick\">\r\n  <b>"
    + alias3(((helper = (helper = helpers.display || (depth0 != null ? depth0.display : depth0)) != null ? helper : alias1),(typeof helper === alias2 ? helper.call(depth0,{"name":"display","hash":{},"data":data}) : helper)))
    + "</b>\r\n</div>\r\n<div id=\"image\">\r\n  <img src=\"http://www.gravatar.com/avatar/"
    + alias3(((helper = (helper = helpers.hash || (depth0 != null ? depth0.hash : depth0)) != null ? helper : alias1),(typeof helper === alias2 ? helper.call(depth0,{"name":"hash","hash":{},"data":data}) : helper)))
    + "?s=32\">\r\n</div>";
},"useData":true};

在我的JS代码中,我做了类似的事情:

$('#profile').html(Handlebars.templates.profile({
    display:'user 1',
    hash:'abdcef....'
}));

当我运行代码时,我收到错误:

TypeError: Cannot read property 'helperMissing' of undefined

与编译的模板代码有关:

...
var helper, alias1=helpers.helperMissing, alias2="function", alias3=this.escapeExpression;
...

我似乎无法找到添加此代码的任何理由,或者在Handlebars文档中对helperMissing函数的任何引用......

对于为什么会发生这种情况的任何见解都将非常受欢迎!

1 个答案:

答案 0 :(得分:1)

最后,问题变成了冲突版本之一!

我最终修复它的方法是稍微更改gulp文件:

gulp.task('build-hbs', function(){
  gulp.src('root/app/src/hbs/*.hbs')
    .pipe(handlebars({
      handlebars: require('handlebars')
    }))
    .pipe(wrap('Handlebars.template(<%= contents %>)'))
    .pipe(declare({
      namespace: 'Handlebars.templates',
      noRedeclare: true // Avoid duplicate declarations
    }))
    .pipe(insert.prepend('var Handlebars = require("handlebars");\n'))
    .pipe(concat('templates.js'))
    .pipe(gulp.dest('root/app/js/templates/'));
});

gulp.task('copy', function(){
  gulp.src('node_modules/handlebars/dist/handlebars.runtime.js')
    .pipe(gulp.dest('root/app/js/libs/'));
});

主要区别在于它专门加载由npm安装的把手版本以用作编译器。

第二个作业将handlebars.runtime.js文件从node_modules文件夹复制到浏览器实际拾取它的文件夹中。这保证了兼容性!

要求wrapdeclare调用以确保编译的代码实际上是正确的(这与手柄网站上的信息不同 - gulp-handlebars模块只适用于有点奇怪的方式)。

最后,insert添加了一个require调用,以确保它以独立方式工作,以确保在运行时满足Handlebars依赖性。

最后,我的模板中有一个错误,应该是:

<div id="nick"><b>{{display}}</b></div>
<div id="image">{{gravatar hash 48}}</div>

gravatar帮助器缺少的第二个参数导致错误 - 只有在编译后的模板工作时才出现,但此时很容易发现!