SQLiteを操作するAirアプリケーションを作成する 5(Update編)
前回DataGridを利用し、DBのデータを表示した。
次は表示したデータを更新してみる
- 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のカラムは表示されない
- 続いて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をする
- 後は単純にUPDATEのSQL文を作成、実行し一覧を再表示してやる。これでDataGrid上で編集できるようになり、DBの更新も行うようになった。
が、一部問題がある。何故か値の入っていないINTEGER型のDataGridを変更しようとすると半角スペースがデフォルトで入ってる状態になってしまう。その為、そのままフォーカスを変えようとすると半角スペースでINTEGER型のカラムを更新しようとし、エラーが発生してしまう。
- DBを直接見ても当然半角スペースは入っていない
- わざとheightをSELECTしないようにし、値の入っていないDataGridのheight列を編集しようとすると空になっている
- TEXT型のカラムは値が入っていなければ元々空で出してくれている