2013年7月1日月曜日

Go の template パッケージと AngularJS の共存

AngularJS では HTML 内に {{}} で囲まれた部分を Angular 文として処理します。
一方、Go の template パッケージも {{}} で囲まれた部分を Go のコードとして処理します。
この2つが衝突してエラーが起きます。

GAE + Go では予め作っておいた HTML テンプレートに変数を展開するのが基本です。
このとき、HTML 内の変数が入る部分に {{.変数名}} という形式で表現します。

一方、AngularJS でも同様に HTML 内に Model の変数を当てはめて出力します。
書式も同じで HTML に {{変数名}} という形式で表現します。

AngularJS の変数を出力するために {{変数名}} を HTML テンプレートに埋め込むと、
Go が「これは Go の変数名だ」と勘違いして変数を探しに行きます。
Go 内で定義されていない変数を参照しようとするため nil pointer エラーが発生します。
runtime error: invalid memory address or nil pointer dereference

衝突を回避するために AngularJS で {{}} を別の記号に変更できます。
app.config(function($interpolateProvider) {
 $interpolateProvider.startSymbol('{[{');
 $interpolateProvider.endSymbol('}]}');
});

これで {{変数名}} が Go の変数を、 {[{変数名}]} が JS の変数を指すようになります。