前回までの状況はこちら。
最新ソースはこちら(gitHub)
https://github.com/takishita2nd/diet-mng
データ編集処理を作成していきます。
やり方は、体重管理機能のものと同じです。
EatingEditDialogComponent.vue
<template>
<div>
<div id="overlay" v-show="show">
<div id="content">
<p v-if="error_flg == true" class="error">
<ui>
<li v-for="error in errors">{{ error }}</li>
</ui>
</p>
<table class="edit">
<tbody>
<tr>
<td>日付</td>
<td>
<input type="date" v-model="contents.date" v-if="datehold" readonly>
<input type="date" v-model="contents.date" v-else>
</td>
</tr>
<tr>
<td>品名</td>
<td><input type="text" v-model="contents.item" /></td>
</tr>
<tr>
<td>時間帯</td>
<td>
<select name="timezone" v-model="contents.timezone">
<option value="1" selected>朝</option>
<option value="2">昼</option>
<option value="3">夜</option>
<option value="4">間食</option>
</select>
</td>
</tr>
<tr>
<td>タンパク質</td>
<td><input type="number" v-model="contents.protein" /></td>
</tr>
<tr>
<td>脂質</td>
<td><input type="number" v-model="contents.liqid" /></td>
</tr>
<tr>
<td>炭水化物</td>
<td><input type="number" v-model="contents.carbo" /></td>
</tr>
<tr>
<td>カロリー</td>
<td><input type="number" v-model="contents.calorie" /></td>
</tr>
</tbody>
</table>
<p id="command">
<button @click="clickEdit">編集</button>
<button @click="closeModal">閉じる</button>
</p>
</div>
</div>
</div>
</template>
<script>
export default {
props: ['show', 'date', 'datehold'],
data() {
return {
errors: [],
error_flg: [],
param: {},
contents: {},
};
},
methods: {
dataSet: function(data) {
this.contents = data;
},
clickEdit: function() {
var self = this;
this.param.contents = this.contents;
axios.post('/api/eating/update', this.param).then(function(response){
self.clear();
self.closeModal();
self.$emit('update');
}).catch(function(error){
self.error_flg = true;
self.errors = error.response.data.errors;
});
},
closeModal: function() {
this.$parent.showEditDialogContent = false;
},
clear: function() {
this.contents.date = this.date;
this.contents.item = "";
this.contents.timezone = 1;
this.contents.protein = "";
this.contents.liqid = "";
this.contents.carbo = "";
this.contents.calorie = "";
this.error_flg = false;
this.errors = [];
}
}
}
</script>
EatingDetailComponent.vue
<eating-edit-dialog-component ref="editDialog" :show="showEditDialogContent" :date="date" :datehold=true @update="invokeUpdateList"></eating-edit-dialog-component>
onClickEdit: function(timezone, id) {
var editData = {};
this.datalists[timezone].forEach(element => {
if(element.id == id){
editData.id = id;
editData.date = this.date;
editData.item = element.item;
editData.timezone = timezone + 1;
editData.protein = element.protein;
editData.liqid = element.liqid;
editData.carbo = element.carbo;
editData.calorie = element.calorie;
return true;
}
});
this.$refs.editDialog.dataSet(editData);
this.showEditDialogContent = true;
},
Editボタンをクリックすると、detail側でEditダイアログに表示するパラメータを作成し、Editダイアログに渡します。
refパラメータを使用することで、親から子のモジュールの関数を呼び出すことができるので、これを利用してパラメータ一式を子モジュールに渡します。
編集ダイアログで編集をクリックすると、APIを呼び出してデータの更新を行います。
ApiController.php
/**
* データを一件取得する
*/
public function update(Request $request)
{
$paramNames = $this->eatingManagement->getParam();
$param = [];
foreach($paramNames as $name) {
$param[$name] = $request->contents[$name];
}
$this->eatingManagement->update($param, Auth::user(), $request->contents['id'], $request->contents['timezone']);
return response()->json();
}
EatingManagementRepository.php
/**
* データを一件取得する
*/
public function update($param, $user, $id, $timezone)
{
$model = $user->EatingManagements()->where('id', $id)->first();
foreach($this->paramNames as $name)
{
$model->$name = $param[$name];
}
$model->save();
$oldtime = $model->timezones()->first();
$newtime = Timezone::where('id', $timezone)->first();
$this->detachToTimezone($model, $oldtime);
$this->attachToTimezone($model, $newtime);
}
データを更新するときは、IDからデータベースのデータを取得し、これのデータを上書きすることで更新できます。
ただ、時間帯の更新というのもありえるので、timezonesテーブルとのリンクを再構築しなければなりません。
いったん、リレーションからtimezonesとデタッチし、新しいtimezonesとアタッチします。
これが終わったら、入力と同様にダイアログを非表示にし、detail画面を更新します。
ちょっと表示に手間取ったけど、できました。