タグ「AngularJS」が付けられているもの

最近、テスト書きながらでコーディングしていますが、 https://github.com/dai-shi/connect-prerenderer のe2eテストで少し困ってます。

AngularJSのブートストラップは通常、

<html ng-app class="ng-app:<modulename>">

とアノテーションをつけることによって行われるのですが、 ある理由からブートストラップを自分で呼びたいと考えています。 これ自体は比較的簡単で、

angular.bootstrap(document, ["<modulename>"]);

を呼び出せばいいだけです。より正確には、

<script>
  angular.element(document).ready(function() {
    angular.bootstrap(document, ["<modulename>"]);
  });
</script>

といったことろです。

ところが!

このブートストラップの方法だと、testacularが動いてくれないのです。困りました。browser().navigateTo(...)を呼び出すと返ってこないのです。

解決策は今のところ見つかっていません。とりあえず、テストするときは、ng-appをつけておくしかありませんね。

https://github.com/dai-shi/connect-prerendererを開発中に出会った事象について書き留めておきます。

jsdomでAngularJSを使ったテストページにアクセスすることになったのですが、 angularが初期化されなくて困ってました。ぐぐったところ、

AngularJSがIE8で動かないときは

を見つけたのですが、この方法では解決せず。結局、次のようにしたら動きました。

<html ng-app class="ng-app">

id="ng-app"はあってもなくても変わらず。モジュールがある場合は、class="ng-app:<modulename>"でもうまくいくのかもしれません。

angularのソースコードを少し眺めると、

function angularInit(element, bootstrap) {
  var elements = [element],
      appElement,
      module,
      names = ['ng:app', 'ng-app', 'x-ng-app', 'data-ng-app'],
      NG_APP_CLASS_REGEXP = /\sng[:\-]app(:\s*([\w\d_]+);?)?\s/;
//-----snipped-----
  forEach(names, function(name) {
    names[name] = true;
    append(document.getElementById(name));
    name = name.replace(':', '\\:');
    if (element.querySelectorAll) {
      forEach(element.querySelectorAll('.' + name), append);
      forEach(element.querySelectorAll('.' + name + '\\:'), append);
      forEach(element.querySelectorAll('[' + name + ']'), append);
    }
  });

ってな感じで、どんな風に書いても動きそうです。なぜ、id="ng-app"でうまくいかなかったのか疑問が残りますが、追求しないことにします。


追記。

ng-appだけではダメだった理由は、ng-app="ng-app"に展開されてしまうからのようなので、ng-app="<modulename>"にすればうまくいくのかもしれません。

さらに、追記。

結局、ng-app=""で動いたので、ng-appだけだとjsdomでうまくいかないというのは正しそうです。class="ng-app:<modulename>"もうまくいきそう。id="ng-app"で動かなかった理由はおそらく、ng-appが残っていたからでしょう。