1

私は現在、ExecJS を使用して、私が取り組んでいる製品の 1 つでハンドルバーを実行しようとしています (注: 本当にクールな handlebars.rb ジェムを知っていて、何度か使用しましたが、Windows にインストールするには問題があります) 、だから私は別の自家製の解決策を試します)。

私が抱えている問題の 1 つは、ExecJS への各 "呼び出し" の間で Javascript コンテキストが保持されないことです。

@js 属性をインスタンス化するコードは次のとおりです。

class Context
  attr_reader :js, :partials, :helpers

  def initialize
    src = File.open(::Handlebars::Source.bundled_path, 'r').read
    @js = ExecJS.compile(src)
  end
end

そして、ここに問題を示すテストがあります:

let(:ctx) { Hiptest::Handlebars::Context.new }

it "does not keep context properly (or I'm using the tool wrong" do
  ctx.js.eval('my_variable = 42')
  expect(ctx.js.eval('my_variable')).to eq(42)
end

そして今、私がそれを実行すると:

rspec spec/handlebars_spec.rb:10                                                                   1 ↵
I, [2015-02-21T16:57:30.485774 #35939]  INFO -- : Not reporting to Code Climate because ENV['CODECLIMATE_REPO_TOKEN'] is not set.
Run options: include {:locations=>{"./spec/handlebars_spec.rb"=>[10]}}
F

Failures:

  1) Hiptest::Handlebars Context does not keep context properly (or I'm using the tool wrong
     Failure/Error: expect(ctx.js.eval('my_variable')).to eq(42)
     ExecJS::ProgramError:
       ReferenceError: Can't find variable: my_variable

注:「eval」ではなく「exec」でも同じ問題が発生しました。

それはばかげた例です。「Handlebars.registerPartial」を実行し、後で「Handlebars.compile」を実行するために本当にやりたいこと。ただし、テンプレートでパーシャルを使用しようとすると、以前に登録されたものが失われるため失敗します。

私は回避策を見つけたことに注意してください。

  def register_partial(name, content)
    @partials[name] = content
  end

  def call(*args)
    @context.js.call([
      "(function (partials, helpers, tmpl, args) {",
      "  Object.keys(partials).forEach(function (key) {",
      "    Handlebars.registerPartial(key, partials[key]);",
      "  })",
      "  return Handlebars.compile(tmpl).apply(null, args);",
      "})"].join("\n"), @partials, @template, args)
  end

問題を解決する方法について何か考えはありますか?

4

1 に答える 1