※随時更新中
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のコード:
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型のリソースの選択状態を判定するケースがある。
List<dynamic> items = [{'id':1, 'name':'one'},{'id':2, 'name':'two'},{'id':3, 'name':'three'}];
NgModel itemsSelect = {};
%ul
%li(ng-repeat='item in items')
%label {{ item.name }}
%label
%input(type='checkbox' ng-model='itemsSelect[item.id]')
例えば、選択状態のリソースを削除したい場合がある。
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)
としなければマッチしない。
void delete(int id) {
...
}
としても、エラーにならない。いつの間にid
はString
になったのか!?わかりません。
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=true
でimplements ShadowRootAware
なComponent
のonShadowRoot(ShadowRoot sr)
メソッド内において、ShadowRoot.querySelector
により対象のinputエレメントを取得する必要がある。 -
onShadowRoot
はimplements ShadowRootAware
なComponent
でしか呼び出されない。 -
window.querySelector
でComponentのテンプレートにアクセスすることはできない。-
ng-show
をトリガーにすると、Componentレンダリング後にwindow.querySelector
でエレメントを取得することができる。
-
- shadow-domをサポートしないブラウザでは、AngularDart経由でHTML5 File APIを使うことはできない。
Component内でdart:async
を使うとエラー
Dart 1.8.5/1.9.1
AngularDart 1.1.0
Component
内にFuture
やTimer
を使った非同期処理を書くと、dartiumでロードした時に次のようなException
がスローされることがある。
Exception: Type 'Component***' not found in generated typeFactory maps. Is the type's constructor injectable and annotated for injection?
これができないと、ボタンアクションと遅延したい処理が分離できず、非常に痛い。
このエラーを回避するには、Future
やTimer
の呼び出しコードを、Component
クラス内のメソッドに直接書くのではなく、別クラスのメソッドにFuture
を返す関数として定義し、これを呼ぶ。
Future
やTimer
内で、DIを越えるクロージャ変数を変更するようなケースで発生するようだ。