서버 통신하기-2. 상세 페이지 보기

HootJem's avatar
Oct 14, 2024
서버 통신하기-2. 상세 페이지 보기
notion image
라우터가 아닌 상태로 페이지를 이동 할 때가 있습니다.
컨텍스트는 내 화면 정보를 갖고 있습니다.
notion image
이 화면에 해당하는 정보를 갖고 있겠죠, 따라서 이전 페이지가 존재해야 상세 페이지로 갈 수있기 때문에 항상 컨텍스트를 갖고 가야합니다.
 

1. 페이지 이동때 매개변수 전달하기

notion image
MaterialPageRoute 로 이동을 하게 되면 라우터와는 다른 장점을 갖습니다. 이는 매개 변수를 들고 갈 수 있다는 점입니다.
notion image
이 페이지로 저 id 값을 들고 갈 것입니다.
notion image
id 를 매개변수로 넘겨주기 때문에 PostDatailPage 에서도 id 를 받아주고, 그림을 그릴 주체인 PostDetailBody 에도 id 값을 전달합니다. (디테일 바디에도 id 를 받을 수 있도록 추가합니다)
notion image
 

2.

notion image
 
PostDetailModel? model = ref.watch(postDetailProvider);
제일 처음은 데이터 전달이 끝나기 전이기 때문에 null 값을 화면에 전송하게 됩니다. (빙글빙글 효과로 인해 보이지 않게 설정할 수 있습니다.) 이때 프로바이더가 watch 를 하고 있으므로, 값이 변경되면 상태변경된 부분만 다시 그리게 됩니다.
 
notion image
프로바이더에 패밀리를 추가하여 int 를 매개변수를 받을 수 있도록 추가하였습니다.
💡
만약 매개변수를 더 넣고싶다면 매개변수들을 클래스로 만들어 넣어야합니다.
notion image
notion image
 
여하튼, 다시 코드로 돌아갑니다.
// 3. 창고 관리자 (Provider) final postDetailProvider = StateNotifierProvider.family<PostDetailVm, PostDetailModel?, int>( (ref, id) { return PostDetailVm(null)..notifyInit(id); });
이제 통신 로직을 짜야 합니다.
지금 하지는 않지만 내용이 하나만 생성되도록 하는 법
매변 새로 생성되게 하지 않게 하려면 const 로 생성하거나, singleton 패턴을 활용할 수 있습니다.
Repository 를 const 로 부름
Repository 를 const 로 부름
Repository 를 싱글톤 객체로 만듬
Repository 를 싱글톤 객체로 만듬
notion image
일단 리턴을 기다리는 값들을 봅니다.
class PostDetailModel { int id; String title; String content; DateTime createdAt; DateTime updatedAt; PostDetailModel.fromMap(map) : this.id = map["id"], this.title = map["title"], this.content = map["content"], this.createdAt = map["createdAt"], this.updatedAt = map["updatedAt"]; }
데이터를 매핑할 녀석들을 만듭니다.
왜 맵에서 꺼내느냐 하면 이 body 에 들어있는 값들을 Map<String, dynamic> 키, 값을 갖고있는 배열 로 보고 있기 때문입니다.
notion image
notion image
이 물음표를 넣지 않는다면 빈 생성자나, 빈 문자열 이라도 넣어야 한다. 그렇게 되면 if 문에서 null 체크를 할 수 없고, 코드가 불편해 진다. 따라서 ? 를 넣어 null 허용 하는 편이 훨 편하다.
 
if 문으로 null 체크 하고 나면 끝.
import 'package:blog/ui/detail/post_detail_vm.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; class PostDetailBody extends ConsumerWidget { int id; PostDetailBody(this.id); @override Widget build(BuildContext context, WidgetRef ref) { PostDetailModel? model = ref.watch(postDetailProvider(id)); if (model == null) { return Center(child: CircularProgressIndicator()); } else { return Padding( padding: const EdgeInsets.symmetric(horizontal: 16), child: Column( children: [ Align( alignment: Alignment.centerRight, child: ElevatedButton( child: Icon(CupertinoIcons.trash_fill), onPressed: () {}, ), ), SizedBox(height: 10), Text("id : ${model.id}", style: TextStyle(fontSize: 20)), Text("title : ${model.title}"), Text("content : ${model.content}"), Text("createdAt : ${model.createdAt}"), Text("updatedAt : ${model.updatedAt}"), ], ), ); } } }
notion image
 

로딩 라이브러리
 

Share article

[HootJem] 개발 기록 블로그