Flutter/MVVM 활용

[Flutter] (MVVM 활용) PostDetailView 화면 완성 하기 - 11

미로910 2024. 11. 22. 16:50
PostListPage 에서 PostDetailPage 위젯 생성
          : ListView.separated(
              itemBuilder: (context, index) {
                Post post = postList[index];
                return ListTile(
                  onTap: () {
                    Navigator.push(context,
                        MaterialPageRoute(builder: (context) {
                      return PostDetailPage(postId: post.id);
                    }));
                  },

 

detailPage
import 'package:class_riverpod_mvvm/providers/state_noti_provider/post_detail_view_model_provider.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

class PostDetailPage extends ConsumerWidget {
  final postId;

  const PostDetailPage({required this.postId, super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    // 화면을 만들기 위해서 뷰 모델이 관리하는 상태(데이터)가 필요하다.
    // postDetailViewModelProvider 에 패밀리 주에 하나를 가져 와야 한다.
    final postState = ref.watch(postDetailViewModelProvider(postId));
    // post <-- 데이터 타입이 뭘까?. AsyncValue<Post> 객체이다.
    return Scaffold(
      appBar: AppBar(
        title: const Text('게시글 상세보기 화면'),
      ),
      body: postState.when(
        data: (post) => Padding(
          padding: EdgeInsets.all(16.0),
          child: Column(
            children: [
              Text(
                post.title,
                style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
              ),
              const SizedBox(height: 16),
              Text(
                post.body,
                style: TextStyle(fontSize: 16),
              ),
            ],
          ),
        ),
        error: (e, stack) => Center(
          child: Text('네트워크 오류 발생'),
        ),
        loading: () => Center(
          child: CircularProgressIndicator(),
        ),
      ),
    );
  }
}

 

detailPageViewModelProvider

// 새로운 개념 추가

import 'package:class_riverpod_mvvm/providers/provider/post_respisitory_provider.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

import '../../models/post.dart';
import '../../view_models/post_detail_view_model.dart';

final postDetailViewModelProvider =
StateNotifierProvider.family<PostDetailViewModel, AsyncValue<Post>, int>((ref, postId) {
  // 1. postId 값은 family 를 통해 전달 받은 외부 매개변수로, 특정 게시글을 식별하는데 사용 된다.
  final postRepository = ref.read(postRepositoryProvider);
  return PostDetailViewModel(postRepository, postId);
});