Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
63
Help us understand the problem. What is going on with this article?
@ukyo

ng-includeの落とし穴

More than 5 years have passed since last update.

htmlを分割したいと思ったときにng-includeはとても便利です。ただし制約もあります。

動きそうで動かないコード

以下の様なコードがあったとします。これはうまく動きそうで動きません。具体的には初期化されたときはHello worldと表示されますが、テキスト欄を変更しても値が更新されることはありません。

index.html
<div ng-controller="Ctrl">
  Hello {{name}}!
  <div ng-include="'path/to/template.html'"></div>
</div>
template.html
<input ng-model="name">
app.js
angular.module('app', []).controller('Ctrl', function($scope) {
  $scope.name = 'world';
});

原因

更新されない原因はng-includeディレクティブが子スコープを作るからです。初期化されたときはng-includeのスコープにはnameプロパティは存在せず親スコープから参照しますが、テキスト欄の値を更新するとng-includeのスコープの方に反映されます。結果、親スコープのnameプロパティは変更されず表示も変わらない、ということになります。

解決法

サーバーサイドでinclude

サーバーサイドでテンプレートをインクルードする方法はいくらでもあるので略。

ディレクティブを作る

以下のようにテンプレートだけ設定されたディレクティブを作ります。

app.directive('foo', function() {
  return {
    template: '<input ng-model="name">'
  };
});
index.html
<div ng-controller="Ctrl">
  Hello {{name}}!
  <div foo></div>
</div>

テンプレートを読み込むだけのディレクティブを作る

ng-includeのようにテンプレートを動的に切り替える必要がないのであれば、以下の様なディレクティブでテンプレートを読みこめば事足ります。

app.directive('myInclude', function($http, $compile) {
  return function(scope, element, attr) {
    $http.get(attr.myInclude).success(function(response) {
      element.html(response);
      $compile(element.contents())(scope);
    })
  };
});
index.html
<div ng-controller="Ctrl">
  Hello {{name}}!
  <div my-include="path/to/template.html"></div>
</div>

一度ディレクティブを作れば、サーバーサイドでのインクルードと似たような書き方ができるので個人的にはこれが一番取っ付きやすいです。

まとめ

ng-includeでhtmlを分割したとき、分割したテンプレートの中にデータを上書きするようなものを入れるとうまく動きません。ng-includeはデータを表示するだけのテンプレートだけを扱い、もしng-model等々使いたい場合は、上に書いたような解決方法を試してみましょう(そもそも規模がでかい場合はui-routerみたいなものを使ったほうがよさそうですが)。

参考

AngularJS: API: ngInclude

63
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ukyo
こんにちはちは
wacul
人工知能でWebサイトの課題を発見する AIアナリスト https://wacul-ai.com を開発しています

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
63
Help us understand the problem. What is going on with this article?