スキップしてメイン コンテンツに移動

AngularDartを利用して Inputタグで画像を読み込むダイアログ。(2) 関数渡しをしてみる

前回のを、もう少し、賢くしてみました。

関数やパラメータを渡せるようにする
初期化しなくても動作するようにする
エラーメッセージ等を呼び出せるようにする


https://github.com/firefirestyle/ebook_windstyle_markdown/tree/master/angular/image-input-dialog/app


dialog.dart

import 'package:angular2/core.dart';
import 'package:angular2_components/angular2_components.dart';
import 'dart:html' as html;
import 'imageutil.dart' as imgutil;
import 'dart:async';


@Component(
  selector: 'inputimage-dialog',
  styles: const [
    """
    .inputimage-dialog-title {
    }
    .inputimage-dialog-message {
    }
    .inputimage-dialog-errormessage {
    }
    .inputimage-dialog-cancelbutton{
    }
    .inputimage-dialog-okbutton{
    }
    """,
  ],
  template: """
<modal #wrappingModal>
  <material-dialog style='width:80%'>
    <div *ngIf='errorMessage!=""' class='inputimage-dialog-errormessage'>{{errorMessage}}</div>
    <h3 class='inputimage-dialog-title' header>{{param.title}}</h3>
    <p class='inputimage-dialog-message'>{{param.message}}</p>
    <material-spinner *ngIf='isloading'></material-spinner>
    <div #imgc></div><br>
    <input #in *ngIf='isloading==false' type="file" id="upload" (change)='onInput(in,imgc)'>
    <div footer>
      <material-button *ngIf='isloading==false' autoFocus clear-size (click)="onCancel(wrappingModal)" class='inputimage-dialog-cancelbutton'>
        {{param.cancel}}
      </material-button>
      <material-button *ngIf='currentImage!=null||isloading==false' autoFocus clear-size (click)="onFile(wrappingModal)" class='inputimage-dialog-okbutton'>
        {{param.ok}}
      </material-button>
    </div>
  </material-dialog>
</modal>
  """,
  directives: const [materialDirectives],
  providers: const [materialProviders],
)
class InputImageDialog implements OnInit {
  @ViewChild('wrappingModal')
  ModalComponent wrappingModal;

  @Input()
  InputImageDialogParam param;

  bool isloading = false;
  html.ImageElement currentImage = null;
  String errorMessage = "";

  ngOnInit(){
    if(param == null) {
      param = new InputImageDialogParam();
    }
  }

  void open() {
    wrappingModal.open();
  }

  onCancel(ModalComponent comp) {
    wrappingModal.close();
  }

  onFile(ModalComponent comp) async {
    isloading = true;
    try {
      var ret = await param.onFile(this);
      if (ret != "" && ret != null) {
        errorMessage = ret;
      } else {
        errorMessage = "";
        wrappingModal.close();
      }
    } catch (e) {
      errorMessage = "failed to (${e})";
    } finally {
      isloading = false;
    }
  }

  onInput(html.InputElement i,html.DivElement c) async {
    isloading = true;
    try {
      c.children.clear();
      if(i.value.length <= 0) {
        return;
      }
      var img = await imgutil.ImageUtil.loadImage(i.files.first);
      var img1 = await imgutil.ImageUtil.resizeImage(img);
      c.children.add(img1);
      currentImage = img1;
    } catch(e){
      errorMessage = "failed to (${e})";
    } finally{
      isloading = false;
    }
  }
}

typedef Future<String> OnFileFunc(InputImageDialog d);

class InputImageDialogParam {
  String title;
  String message;
  String ok;
  String cancel;
  int get imgWidth => 300;
  int get imgHeight => -1;
  OnFileFunc onFileFunc;

  InputImageDialogParam({this.title:"File",this.message:"select file!!",this.ok:"OK",this.cancel:"Cancel",
  onFileFunc: null}){
  }

  /**
   * if failed to do onFind func, then return error message.
   */
  Future<String> onFile(InputImageDialog d) async {
    if (onFileFunc == null) {
      return "";
    } else {
      return onFileFunc(d);
    }
  }
}

====


main.dart


import 'package:angular2/platform/browser.dart';
import 'package:angular2/core.dart';
import 'dialog.dart';

void main() {
  bootstrap(AppComponent);
}

@Component(
    selector: "my-app",
    directives: const [InputImageDialog],
    template: """
    <div>
    <h1>Dialog Test</h1>
    <div>
    <button (click)='onClick(myDialoga)'>open</button>
    </div>
    <inputimage-dialog #myDialoga [param]='param'>
    </inputimage-dialog>
    </div>
  """
)
class AppComponent implements OnInit {
  final InputImageDialogParam param = new InputImageDialogParam();

  AppComponent();
  ngOnInit() {
  }
  onClick(InputImageDialog _dialog) async {
    _dialog.open();
  }
}

====

InputImageDialogParam を用意して、デフォルト値を持たせるようにして
初期化は必須で無くした。

onFIle()メソッドを追加して、後から機能を拡張できるようにしてみた。


うーむ
徐々に汎用的な部品が作れるようになってきたかな。
まだ、微妙かな



コメント

このブログの人気の投稿

KyoroStressの技術 -1- Low Memory Killer を意図的に発生させたい

[課題] Low Memory Killer を意図的に発生させたい Androidには、ヒープが涸渇すると使われていないアプリをKillする機能があります。 この記事では、意図的にヒープを枯渇させて、この状態をつくる方法について説明します。 単純にヒープを大量に消費するアプリを作成すれば良いように思えます。 しかし、これだけでは上手くいきません。   -A ひとつのアプリで消費できるヒープが制限されているため、ひとつのアプリで端末のヒープが涸渇している状態をつくれない。   -B ヒープを涸渇しているアプリがPFにKILLされる場合がある。 といった問題があります。 KyoroStressV2での解決方法を紹介します。 [KyoroStressでの解決方法] Kyoro Stress では、以下のような方法をとりました。 - 1. 複数のServiceを、各々異なるプロセスで起動する。 - 2. 各々Serviceで大量のヒープを消費する。 複数のプロセスを立ち上げれば、PFのヒープを枯渇させることができます。これで、(A)の問題が解決できました。 また、Bについては、「生きているプロセス」が「KILLされたプロセス」の分もヒープを消費すれば上手くいけそうです。 [BigEater(ヒープ消費サービス)の動作] KyoroStressV2で、ヒープを消費するサービスは以下のシナリオで動作しています。 - 1. 指定されたヒープを取得する。 is retry が true の時、指定されたヒープを取得できるまで、1を何度も繰り返す。 - 2. KILLされたサービスを復活させる。 is retry が true の時、Threadが死ぬまで、何度も2を繰り返す。 - 3. 終了 といった感じです。 このままでは、すべてのServiceがPFにKILLされたら上手くいかないように思うかも知れません。 しかし、時間がたつと(数秒)、PFはKILLしたServiceを再起動します。 このため、ServiceがすべてKILLされても、ヒープを大量に消費しようとする状態は保持されます。 [使い方] KyoroStressV2の操作方法…

P2P探訪 STUNでNAT越え その1

UPnPを用いて、NAT越えできました。しかし、ルータがUPnPをサポートしていなかったり。UPnPだけでは越えられないNATがあります。

本文では、その代案として前回解説できなかった。「適当なサーバーに接続してみて、相手から見えているアドレスを返してもらう方法」について解説していきます。

TCPの限界 インターネットで公開されている情報のほとんどは、TCPという通信方法でデータをやり取りされています。ですから、インターネットで情報を公開したい場合は、TCPサーバーを立ち上げる事を考える事でしょう。
 しかし、ルータがUPnPをサポートしていない場合、TCPを用いたサーバーを運用する事は困難になります。※ 基本、無理と考えもらって問題ありません。


接続相手から教えてもらう方法はどうした? 適当なサーバーに接続してみて、相手から見えているアドレスを返してもらう事で実現できないのでしょうか。前回はできそうな事を臭わせていました。しかし、TCPにおいて、これは困難です。

実際にTCPのプログラムを書き確認して見ましょう。接続相手のホストアドレスは推測できます。しかし、ポート番号を知るすべはありません。


import java.io.IOException; import java.net.Inet4Address; import java.net.ServerSocket; import java.net.Socket; import java.net.UnknownHostException; public class TCPTest { public static void main(String[] args) { TCPTest test = new TCPTest(); test.startServer(); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } test.startClient(); } private Server mServer = new Server(); public void startServer() { mServer.start(); } public v…

P2P探訪 Raider その1-2 Torrentファイルフォーマット

というわけで、前回に引き続いて、この記事ではTorrentファイルについて説明します。 [Torrent file format] 前回、Bencodingを実装したのでTorremt Fileを読み込めることができるようになりました。 今回は、Torrentファイルから必要な情報を読み込む方法について解説します。 torretファイルから取得できる情報はどんなものかは、別の機会に解説します。 ここでは、torrentファイルには 2つのフォーマットがあることとデータ構造を説明します。 たとえば、「"announce"というデータが何なのか?」については解説しません。 torrentファイルでは、ダウンロード/アップロードの対象としているファイルが、ひとつの場合と複数の場合で構造がすこしだけことなります。 ひとつの時を、「single file」 複数の時を「multi file」と呼ぶことにます。 では、データ構造を紹介します。 - single file pattern bendiction benstring "announce" beninteger "creation date" bendiction "info" beninteger "length" benstring "name" beninteger "piece length" bebstring "pieces" - multi file pattern bendiction benstring "announce" beninteger "creation date" bendiction "info" benlist "files" bendiction beninteger "length" benlist "path" benstring be…