【问题标题】:Why does Handlebars change the scope of the data we're passing to it?为什么 Handlebars 会改变我们传递给它的数据的范围?
【发布时间】:2014-02-24 16:14:47
【问题描述】:

假设我有以下“类”:

function Person( firstname, lastname ) {
   this.attributes = {};
   this.attributes.name = firstname + ' ' + lastname;
}

Person.prototype.name = function() {
  return this.attributes.name;
};

当我将此对象传递给渲染器时

var myPerson = new Person( "Bob", "Robert" );

var template = Handlebars.compile( "<div>{{person.name}}</div>" );

var data = {person: myPerson, courseName: "LOG210"}

template( data );

问题是上述函数中的 this 关键字不再局限于 Person 实例。相反,它的范围是传递给 Handlebars 的数据。

例如,handlebars调用data.person.name()函数时,this.attributes.namethis变量的作用域> 是对象数据 ({person: myPerson, courseName: "LOG210"}) 不是 myPerson 对象。

原因似乎在于handlebars-v1.3.0

// Template is only compiled on first use and cached after that point.
return function(context, options) {
  if (!compiled) {
    compiled = compileInput();
  }
  return compiled.call(this, context, options);
};

为什么范围会改变?有解决方法吗?

【问题讨论】:

  • 解决方法:在构造函数中声明你的name方法并且已经绑定:this.name = function(){ return this.attributes.name }.bind(this);
  • 有趣,但不允许原型继承。
  • JavaScript 原型不是完整的经典对象,没有继承支持。所以最好的方法是做不同的设计而不是经典的继承

标签: javascript scope this handlebars.js


【解决方案1】:

Handlebars 不会假设您将原型传递给它。

Handlebars 工作(并假设)您正在使用普通对象和助手。解决方法是使用 helper 进行函数调用而不是直接函数调用(其中车把更改范围)。

帮手

Handlebars.registerHelper('ct', function(obj, fn) {
  return obj[fn]();
});

模板

var template = Handlebars.compile( "<div>{{ct person 'name'}}</div>" );

这是工作小提琴http://jsfiddle.net/dp54p/

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2018-09-03
  • 2021-09-26
  • 1970-01-01
  • 1970-01-01
  • 2019-06-29
  • 1970-01-01
相关资源
最近更新 更多