SQLiteを操作するAirアプリケーションを作成する 5(Update編)

前回DataGridを利用し、DBのデータを表示した。

次は表示したデータを更新してみる

  1. DataGridを下記の様に変更する
    <mx:DataGrid id="dg" width="100%" height="100%" dataProvider="{dp}" editable="true" itemEditEnd="update(event)">
      <mx:columns>
        <mx:DataGridColumn editable="false"/>
        <mx:DataGridColumn dataField="id" headerText="Id" visible="false"/>
        <mx:DataGridColumn dataField="name" headerText="Name" />
        <mx:DataGridColumn dataField="height" headerText="Height" />
        <mx:DataGridColumn dataField="weight" headerText="Weight" />
        <mx:DataGridColumn dataField="bust" headerText="Bust" />
        <mx:DataGridColumn dataField="waist" headerText="Waist" />
        <mx:DataGridColumn dataField="hip" headerText="hip" />
        <mx:DataGridColumn dataField="birthday" headerText="Birthday" />
        <mx:DataGridColumn dataField="age" headerText="Age" />
      </mx:columns>
    </mx:DataGrid>
    
    • editable="true"でDataGridのカラムの変更を許可する
    • itemEditEnd="update(event)はカラムが変更された時にこのfunctionを呼ぶという指定になる
    • 表示項目に選択させやすくする為だけの空のカラムを追加し、editable="false"にする。これでこのカラムだけは編集出来ない
    • 表示項目にIDを追加し、visible="false"にする。これでIDのカラムは表示されない
  2. 続いてupdateのfunctionを追加する
    private function update(event:DataGridEvent):void {
       if (event.reason == DataGridEventReason.CANCELLED) {
          return;
       }
        
       var dg:DataGrid = event.currentTarget as DataGrid;
       var item:Object = event.itemRenderer.data;
       var dataField:String = event.dataField;
       var itemEditor:Object = dg.itemEditorInstance;
       
       if (itemEditor.text == item[dataField]) {
          return;
       }
       //原因不明。後述
       if (itemEditor.text == ' ') {
        		       return;
       }
       
       stmt = new SQLStatement();
       stmt.sqlConnection = sqlConn;   
       stmt.text = "UPDATE idol SET "+ dataField + "= :" +dataField +
       " WHERE id = :id";
       
       stmt.parameters[":id"] = item.id;
       stmt.parameters[":"+dataField] = itemEditor.text;
          
       try{
          stmt.execute();
          get();
          successResult();
       }catch(error:Error){
          errorResult(error);
       }
    }
    
    • event.reason == DataGridEventReason.CANCELLEDは編集を取り消したかどうかを判定している。取り消されていたらreturnする
    • event.currentTargetはイベントを投げてきたオブジェクトを指す。event.currentTargetで取れるデータはobject型なのでas DataGridでキャストしてやる
    • event.itemRenderer.dataはdataProviderのアイテムを指す
    • event.dataFieldは列のフィールド名を指す
    • dg.itemEditorInstanceは編集しようとしてるカラムを指す
    • つまりitemEditor.text == item[dataField]で現在のDataGridの値とdataProviderの値を比較し、変更されていなければreturnをする
  3. 後は単純にUPDATEのSQL文を作成、実行し一覧を再表示してやる。これでDataGrid上で編集できるようになり、DBの更新も行うようになった。
    が、一部問題がある。何故か値の入っていないINTEGER型のDataGridを変更しようとすると半角スペースがデフォルトで入ってる状態になってしまう。その為、そのままフォーカスを変えようとすると半角スペースでINTEGER型のカラムを更新しようとし、エラーが発生してしまう。
    • DBを直接見ても当然半角スペースは入っていない
    • わざとheightをSELECTしないようにし、値の入っていないDataGridのheight列を編集しようとすると空になっている
    • TEXT型のカラムは値が入っていなければ元々空で出してくれている
    とちょっと原因が分からない状態。dp = new ArrayCollection(result.data);の時に何か起こってるのかなあと思うのだけど、まず良いデバッグ方法を見つけるのが先かもしれない