AngularDart、最低限これだけあれば開発できるってのをまとめてみた。細かいとこは端折ってるので、他サイト見てね。
##Dart
Flutter/Dartの入門サイトが多数あるので、初期設定する。
IDEはVSCodeがおすすめ。
Inteli Jがいいってサイトも多数あり。
なので、若干キモいけどAndroidStudioでも開発できる。
とりあえず雛形生成して、IDEで開く。
stagehand web-angular
pub get
webdev serveするとローカルで動く。auto restartはセッションとかがダメで、そのうちできなくなるのであてにしない。
##コンポーネントはhtml用コードで一対一が基本
xx_component.html/xx_component.dartで1画面を構成する。雛形を参考に。
複数画面あるときはコンポーネントを複数作る。
複数にしたら、appコンポーネントに追加する。
directives: [
routerDirectives,
ProductsComponent,
ListComponent,
],
##html側 {{インスタンス変数}}/ngIf/ngFor/(click)
<img src="{{header}}">
<p>{{item['price']}}</p>
xx_component.dartのインスタンス変数がhtml側から参照できるので、htmlに{{インスタンス変数名}}とかで埋め込む。
itemがMapのときは「item['price']」とか書ける。つーかDartコードを埋め込める。
<p class="price {{(downloaded[item['key']]!=null)?'downloaded':''}}">{{item['price']}}</p>
dartそのまんま。
<img *ngIf="!headerLink" class="thumbnail" src="{{header}}">
タグ内にifを書ける。falseのときはimgタグが無くなる。使うにはコンポーネントのdirectivesに追加する。NgForも同様。NgSwitchとかもある。
directives: [NgIf, NgFor],
当然Listでループできる。
<li *ngFor="let item of citem['items']; let idx=index">
</li>
コンポーネントのonClickMore(int idx,var citem)でクリックを受け取れる。
<a class="categoryTitle" (click)="onClickMore(idx,citem)">
固定値クラスとかもhtmlから参照できる。コンポーネントのexportsに追加する。
exports: [MyString,MyStrId,Constant],
てやると
<a *ngIf="downloaded[product['key']]==Constant.ITEM_DOWNLOADED" class="getButton downloaded">{{MyString.get(MyStrId.downloaded)}}</a>
とかね。素敵。
##パイプ
<div innerHtml="{{product|lang:'description'|mynl2br}}"></div>
パイプで整形できる。nl2brがなぜか動かなかったので、そのまんまコピーで自作で作ってみた。langも自作でMapから設定言語にしたがったアイテム持ってくるやつ。
@Pipe('mynl2br')
class MyNl2brPipe implements PipeTransform {
String transform(String value, [bool isXhtml = false]) {
// ignore: avoid_positional_boolean_parameters
if (value == null) return "";
return value.replaceAll(RegExp(r'\r?\n'), isXhtml ? '<br/>' : '<br>');
}
}
コンポーネント側。commonPipesに色々入ってる。
pipes: [commonPipes, MyNl2brPipe],
##画面遷移(Router)
複数画面切り替える時は、Routerを導入する。呪文がたくさん必要。
angular_routerを追加。alphaだよ。
pubspec.yaml
dependencies:
angular: ^5.3.0
angular_components: ^0.13.0
angular_router: ^2.0.0-alpha+22
final InjectorFactory injector = self.injector$Injector;
void main() {
//アプリ起動
runApp(ng.AppComponentNgFactory, createInjector: injector);
}
routes.dart追加して、URLを定義
class RoutePaths {
///URL セット
static final setp = RoutePath(path: 'set');
///URL カード表
static final cfp = RoutePath(path: 'cf');
///その他全部
static final allp = RoutePath(path: '.+');
}
class Routes {
static final all = <RouteDefinition>[
RouteDefinition(
routePath: RoutePaths.setp,
component: product_temp.ProductsComponentNgFactory,
additionalData: {
"type": RoutePaths.setp.path,
"index": 0,
"css": "setList"
}),
RouteDefinition(
routePath: RoutePaths.cfp,
component: product_temp.ProductsComponentNgFactory,
additionalData: {
"type": RoutePaths.cfp.path,
"index": 1,
"css": "cFrontList"
}),
];
}
appコンポーネントのhtmlはこうする。
<router-outlet [routes]="Routes.all"></router-outlet>
index.htmlは全画面共通な感じになる。cssとかも。
<body>
<my-app>Loading...</my-app>
</body>
コンポーネントでこんなんで遷移できる。
Future<NavigationResult> onClickMore(int idx, Map item) {
return router.navigate(
RoutePaths.setp.path,
NavigationParams(queryParameters: {
"type": item["type"],
"index": "$idx",
"class": cssClass
}));
}
routerは注入してくれる。
XxComponent(this.productsService, this.router);
こういう風にも書ける。
<a [routerLink]="item['url']"
[routerLinkActive]="'active-route'">{{item|lang:"name"}}</a>
##http通信
データはサービスで持つらしいぞ。
class ProductsService {
//シングルトンのはずがなぜかだめなので、とりあえずstatic
static List<Map<String, String>> _types;
final Client _http;
コンストラクタに引数追加すると、入れてくれる。
ProductsService(this._http) {
}
なんか呪文が必要だったけど、後ほど・・・
final response = await _http.get(ここにURL);
##リリースビルド
webdev build
すると、build以下にビルドされる。それをサーバーに持ってくだけ。
packagesはリリース時は要らないので、削除する。
##ビルドエラー
最近のバージョンはwebdevが頻繁にビルドエラー出すバグがある。
.dart_tool/build以下を消すと、概ね、直る。
##最後に
調べるの、ちょっと時間かかったけど、概ねこれだけ。Dartできれば数日で結構慣れる。あまり深く考えないで、雛形に従う。
慣れるとめっちゃサクサク開発できる。幸せが訪れる。たまにハマると非常に困る
呪文はちょっと端折ってるので、そのうち追加予定。
##その後
パソコン上で開発してて、実機で確認とかもできる。
webdev serve --hostname=IPアドレス
な感じ