前回までの状況はこちら。
最新ソースはこちら(gitHub)
https://github.com/takishita2nd/diet-mng
今回はこの画面を作成していきます。
前回作成した画面の、
Editをクリックしたときの、遷移先の画面です。
まずは、画面遷移のところを作成する。
EatingListComponent.vue
<td class="edit"><a @click="onClickEdit(data.date)">Edit</a></td>
export default {
data() {
return {
url: "eating/detail"
};
},
methods: {
onClickEdit: function(date) {
window.location = this.url + "/" + date;
},
Editをクリックすると、onClickEdit()が実行され、window.locationにURLを設定することで、そのURLに遷移します。
で、遷移先の画面。
web.php
Route::get('/eating/detail/{date}', 'Eating\EatingController@detail')->name('eating/detail');
EatingController.php
class EatingController extends Controller
{
public function detail($date)
{
return view('eatingdetail', ['date' => $date]);
}
eatingdetail.blade.php
@extends('layouts.app')
@section('content')
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading">食事管理</div>
<div class="panel-body">
@if (session('status'))
<div class="alert alert-success">
{{ session('status') }}
</div>
@endif
</div>
<eating-detail-component date={{$date}}></eating-detail-component>
</div>
</div>
</div>
</div>
@endsection
詳細画面のURLはeating/detail/(日付)となります。
この(日付)の部分が巡り巡って、eating-detail-componentに渡ります。
<eating-detail-component date={{$date}}></eating-detail-component>
ここで一度詰まった。
:date={{$date}}と書いてはダメみたい。
で、表示するデータの取得。
class EatingManagementRepository
{
private $paramNames = ['date', 'item', 'protein', 'liqid', 'carbo', 'calorie'];
public function getDetails($user, $date)
{
$eatings = $user->EatingManagements()
->where(DB::raw('date_format(date, "%Y-%m-%d")'), $date)
->get();
$retDatas = [];
$index = [0, 0, 0, 0];
foreach($eatings as $eating) {
$timezone = $eating->timezones()->first();
for($j = 1; $j < count($this->paramNames); $j++) {
$retDatas[$timezone->id - 1][$index[$timezone->id - 1]][$this->paramNames[$j]] = $eating->{$this->paramNames[$j]};
}
$index[$timezone->id - 1]++;
}
return $retDatas;
}
今回もかなりカオスな処理。
時間帯によってデータを分けたかったので、
retData[時間帯番号][index][詳細データ]
という形にデータを作成しています。
詳細データの連想配列の名前は、定義済みの$paramNamesの値を使用します。
これをAPIで呼び出します。
class ApiController extends Controller
{
/**
* 一日分のデータを取得する
*/
public function detail(Request $request)
{
return response()->json(['dataLists' => $this->eatingManagement->getDetails(Auth::user(), $request->contents['date'])]);
}
web.php
Route::post('api/eating/detail', 'Eating\ApiController@detail');
<template>
<div>
<div>
<p id="navi">> <a href="/home">HOME</a> / <a href="/eating">食事管理</a></p>
<p>{{date}}</p>
<table class="eatingdetail">
<caption>朝</caption>
<tbody>
<tr>
<th class="item">品名</th>
<th class="protein">タンパク質</th>
<th class="liqid">脂質</th>
<th class="carbo">炭水化物</th>
<th class="calorie">カロリー</th>
<th class="edit"></th>
</tr>
<tr v-for="data in datalists[0]">
<td class="item">{{ data.item}}</td>
<td class="protein">{{ data.protein}}</td>
<td class="liqid">{{ data.liqid}}</td>
<td class="carbo">{{ data.carbo}}</td>
<td class="calorie">{{ data.calorie}}</td>
<td class="edit"><a @click="onClickEdit(data.date)">Edit</a></td>
</tr>
</tbody>
</table>
<table class="eatingdetail">
<caption>昼</caption>
<tbody>
<tr>
<th class="item">品名</th>
<th class="protein">タンパク質</th>
<th class="liqid">脂質</th>
<th class="carbo">炭水化物</th>
<th class="calorie">カロリー</th>
<th class="edit"></th>
</tr>
<tr v-for="data in datalists[1]">
<td class="item">{{ data.item}}</td>
<td class="protein">{{ data.protein}}</td>
<td class="liqid">{{ data.liqid}}</td>
<td class="carbo">{{ data.carbo}}</td>
<td class="calorie">{{ data.calorie}}</td>
<td class="edit"><a @click="onClickEdit(data.date)">Edit</a></td>
</tr>
</tbody>
</table>
<table class="eatingdetail">
<caption>夜</caption>
<tbody>
<tr>
<th class="item">品名</th>
<th class="protein">タンパク質</th>
<th class="liqid">脂質</th>
<th class="carbo">炭水化物</th>
<th class="calorie">カロリー</th>
<th class="edit"></th>
</tr>
<tr v-for="data in datalists[2]">
<td class="item">{{ data.item}}</td>
<td class="protein">{{ data.protein}}</td>
<td class="liqid">{{ data.liqid}}</td>
<td class="carbo">{{ data.carbo}}</td>
<td class="calorie">{{ data.calorie}}</td>
<td class="edit"><a @click="onClickEdit(data.date)">Edit</a></td>
</tr>
</tbody>
</table>
<table class="eatingdetail">
<caption>間食</caption>
<tbody>
<tr>
<th class="item">品名</th>
<th class="protein">タンパク質</th>
<th class="liqid">脂質</th>
<th class="carbo">炭水化物</th>
<th class="calorie">カロリー</th>
<th class="edit"></th>
</tr>
<tr v-for="data in datalists[3]">
<td class="item">{{ data.item}}</td>
<td class="protein">{{ data.protein}}</td>
<td class="liqid">{{ data.liqid}}</td>
<td class="carbo">{{ data.carbo}}</td>
<td class="calorie">{{ data.calorie}}</td>
<td class="edit"><a @click="onClickEdit(data.date)">Edit</a></td>
</tr>
</tbody>
</table>
</div>
</div>
</template>
<script>
export default {
props: {
date: String
},
data() {
return {
showInputDialogContent: false,
showEditDialogContent: false,
showDeleteDialogContent: false,
datalists: [],
param: {},
contents: {
date: "",
},
};
},
created: function() {
this.updateList();
},
methods: {
onClickEdit: function(date) {
},
invokeUpdateList: function() {
},
updateList: function() {
this.datalists = [];
this.contents.date = this.date;
this.param.contents = this.contents;
var self = this;
axios.post('/api/eating/detail', this.param).then(function(response){
response.data.dataLists.forEach(element => {
var data = [];
element.forEach(element2 => {
data.push({
item: element2.item,
protein: element2.protein,
liqid: element2.liqid,
carbo: element2.carbo,
calorie: element2.calorie
})
})
self.datalists.push(data);
});
}).catch(function(error){
});
}
}
}
</script>
responseの処理がネストになるという、またまたカオスな処理。
でもこれでJS側でもdatalists[時間帯ID][index].詳細データという形になります。
これをテンプレートに表示させれば良い。