LoginSignup
0
0

More than 5 years have passed since last update.

Dartのハマらないためのメモ

Last updated at Posted at 2015-08-05

※随時更新中

Dart

Internet Explorer

  • Internet Explorerのサポートは、IE10 & IE11
  • IE9は、Dart 1.5まで

Google OAuth 2.0

Dart 1.8.5

  • google_oauth2_clientは、Dartのwindow.crypto.getRandomValuesを使用している。
  • https://github.com/dart-gde/dart-google-oauth2-library/blob/master/lib/src/browser/utils.dart
  • Internet Explorer 11に実在するのは、window.msCrypto.getRandomValuesである。
  • Internet Explorer 11のドキュメント上は、window.Crypto.getRandomValuesに存在することになっているが、実在していない。
  • window.msCryptoを参照するように、google_oauth2_clientを変更しても、dart2jsがwindow.cryptoに変換してしまう。(dart:js経由なら、うまく動くかもしれない)
  • Internet Explorer 11でwindow.msCryptoを参照するようにするには、dart2jsが生成したJavaScriptファイルを直接編集する、もしくはdart2jsを変更しなければならない。

以下、window.msCrypto.getRandomValuesをfallbackするための、Makefileのコード:

Makefile
    if [ "$(shell uname)" == "Darwin" ] ; then\
        sed -i "" "s%\\(window.crypto.getRandomValues\\)\\((y)\\)%if(window.crypto==null)window.msCrypto.getRandomValues\2/\*Fallback for IE 11\*/"\\$$'\n'"else \1\2%g" $@;\
    else\
        sed -i    "s%\\(window.crypto.getRandomValues\\)\\((y)\\)%if(window.crypto==null)window.msCrypto.getRandomValues\2/\*Fallback for IE 11\*/"'\n'"else \1\2%g" $@;\
    fi;

Google Cloud Endpoints

discovery_api_client_generator: version 0.4.5

  • Google Cloud Endpointsのpathにuploadが含まれると、discovery_api_client_generatorが生成したクライアントライブラリの内部実装の都合により衝突する。
  • Google Cloud Endpointsのpathにuploadを含めてはならない。uploaderなら問題ない。
  • おそらくここら辺が原因。(実際のエラーメッセージと突合していない)
  • requestも同様かもしれない。
  • v0.5以降は、実装が大幅に変わっているので、問題ないかもしれない。

Dart VMのメモリ割り当てを設定する

GCEのf1-microインスタンスでpub buildしているとOut of memoryでプロセスを切られたりする。
Dart VMにはheapサイズを設定するオプションがある。
設定オプションの詳細はdart --help -vで確認できる。

$ dart --help -v|grep old_gen_heap_size
old_gen_heap_size: 0 (Max size of old gen heap size in MB, or 0 for unlimited,e.g: --old_gen_heap_size=1024 allows up to 1024MB old gen heap)

GCEのf1-microインスタンスの場合は、

$ export DART_VM_OPTIONS="--old_gen_heap_size=416"

くらいに設定しておくと一応死なない。

Allocate more RAM for the Dart VM

AngularDart

まず、CHANGELOGのBreaking Changesを穴のあくほど読み込まなければならない。
https://github.com/angular/angular.dart/blob/master/CHANGELOG.md

  • 古いサンプルコードのほとんどは、現行バージョン下では動かない。

NgModelのkeyはStringへ勝手にキャストされている

一見、何がなんだか理由がわからない。
よくあるUIパターンで、List型のリソースの選択状態を判定するケースがある。

component.dart
List<dynamic> items = [{'id':1, 'name':'one'},{'id':2, 'name':'two'},{'id':3, 'name':'three'}];
NgModel itemsSelect = {};
template.haml
%ul
  %li(ng-repeat='item in items')
    %label {{ item.name }}
    %label
      %input(type='checkbox' ng-model='itemsSelect[item.id]')

例えば、選択状態のリソースを削除したい場合がある。

component.dart
void delete(id) {
  for (int i = items.length - 1; i >= 0; i--) {
    if (items[i].id == id) {
      items.removeAt(i);
    }
  }
}

ここでのitems[i].id == idはマッチしない。なんとitems[i].id == int.parse(id)としなければマッチしない。

component.dart
void delete(int id) {
...
}

としても、エラーにならない。いつの間にidStringになったのか!?わかりません。

Map<int, dynamic> itemsSelect = new Map();ではなくてNgModel itemsSelect = {};なんだから当たり前だろう、と思うかもしれないが、Map<int, dynamic> itemsSelect = new Map();とかしても、keyはStringになるし、エラーは起こらない。
厳密にはNgModelの問題ではなくて、テンプレートに起因しそうだ。

これを根本的に回避するには、リソースの設計時点でkeyに使われそうな数値型の値を文字列型にすることである。

<form action=''>

AngularDart 1.1.0

  • <form>action属性を動的に書き換えたい場合は、<form action='{{ url }}'>としなければならない。
  • <form ng-attr-action='url'>としても、DOM上はaction属性値が書き換わるにもかかわらず、submitが動作しない。何が起こっているか不明だが、とにかく何も起こらない。

HTML5 File API

AngularDart 1.1.0

  • AngularDartのNgModel<input type='file'>をサポートしていない。
  • DartのFile APIをAngularDartのComponentで利用するには、useShadowDom=trueimplements ShadowRootAwareComponentonShadowRoot(ShadowRoot sr)メソッド内において、ShadowRoot.querySelectorにより対象のinputエレメントを取得する必要がある。
  • onShadowRootimplements ShadowRootAwareComponentでしか呼び出されない。
  • window.querySelectorでComponentのテンプレートにアクセスすることはできない。
  • shadow-domをサポートしないブラウザでは、AngularDart経由でHTML5 File APIを使うことはできない。

Component内でdart:asyncを使うとエラー

Dart 1.8.5/1.9.1
AngularDart 1.1.0

Component内にFutureTimerを使った非同期処理を書くと、dartiumでロードした時に次のようなExceptionがスローされることがある。

Exception: Type 'Component***' not found in generated typeFactory maps. Is the type's constructor injectable and annotated for injection?

これができないと、ボタンアクションと遅延したい処理が分離できず、非常に痛い。
このエラーを回避するには、FutureTimerの呼び出しコードを、Componentクラス内のメソッドに直接書くのではなく、別クラスのメソッドにFutureを返す関数として定義し、これを呼ぶ。

FutureTimer内で、DIを越えるクロージャ変数を変更するようなケースで発生するようだ。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0