web-dev-qa-db-ja.com

srcからテキスト/テン​​プレートスクリプトを含めることができますか?

バックボーン、アンダースコア、Parseを使用して基本的なアプリを作成しようとしていました。

私のindex.htmlに、次のようなスクリプトを含めてみました。

<script data-main="js/main" src="../bower_components/requirejs/require.js"></script>
<script type="text/template" id="login-template" src="js/templates/login.js">

バックボーン部分で次のことをしようとすると、うまくいきませんでした。

template: _.template($('#login-template').html());
// ...
render: function() {
    this.$el.html(this.template());
}

ただし、スクリプトを変更し、HTMLドキュメントに直接追加すると、問題なく動作しました。

<script type="text/template" id="login-template">
  <header id="header"></header>
  <div class="login">
    <form class="login-form">
      <h2>Log In</h2>
      <div class="error" style="display:none"></div>
      <input type="text" id="login-username" placeholder="Username" />
      <input type="password" id="login-password" placeholder="Password" />
      <button>Log In</button>
    </form>
</script>

どうしてこれなの?外部ソースのテンプレートを<script>タグに含める方法はありますか?

(この場合は$.getを使用できません。これは、現時点ではWebサーバーを使用することになっておらず、XHRエラーが通常どおり発生し続けるためです。)

27
corvid

機能しない理由

<script>タグのsrc属性により、ブラウザはlogin.jsに対してHTTPリクエストを発行します。ただし、DOMに応答を挿入することはありません。コードが機能するためには、それが必要になります。

ブラウザは、 HTML5仕様 がそうするべきだと言っていないという単純な理由でこれを行いません。

特に、 scripting spec には、<script>タグを準備するときにユーザーエージェントが実行する必要がある アクションのリストがあります およびそのソースを実行します。これらのリストは、ブラウザにスクリプトのソースをDOMに挿入するように指示しません。スクリプトソースが既にDOMにあるため、インラインアプローチが機能します。

この動作は、src属性を持つ<script>タグを検査することで確認できます。そのソースをロード、解析、実行すると、子ノードが含まれなくなります。

あなたができること

AJAXリクエストを使用してテンプレートをロードすることができますが、お勧めしません-アプリケーションに少数のテンプレートがある場合、それらをメインのHTMLファイルに含めるだけの方が簡単です。複数ある場合は、それらをフェッチするために多くのサーバーラウンドトリップが必要になります。

通常、最善の解決策は、テンプレートをJavaScriptファイル内の単一のオブジェクトにコンパイルするビルドステップです。これは、他のスクリプトと同様に含めることができます。

テンプレートをAppTemplatesという変数にコンパイルするこのようなステップを使用すると、コードは次のようになります。

template: AppTemplates['templates/login.tpl']

Grunt には、Underscore.jsテンプレートに対してこれを行う grunt-contrib-jst というタスクがあります。他のテンプレートエンジンと同等のタスクがあります。

32
joews