본문 바로가기

Flutter

riverpod 과 MVVM 활용 - PostDetailViewModel 만들기(상세보기 화면 데이터 관리) (9)

PostListPage - onTab() 추가
      onTap: () {
        Navigator.push(context,
            MaterialPageRoute(builder: (context) {
          return PostDetailPage();
        }));
      }

 

 

 

PostDetailPage 기본 화면 설정
import 'package:flutter/material.dart';


class PostDetailPage extends StatelessWidget {
  const PostDetailPage({super.key});

  @override
  Widget build(BuildContext context) {
    print("여기는 상세보기 화면 입니다.");
    return const Placeholder();
  }
}

 

 

 

PostDetailViewModel 생성
// 뷰 모델 --> 무조건 StateNotifier 상속 받자
// StateNotifier --> 관리해야 하는 상태값은 뭘까?
// StateNotifier <-- 상태는 캡슐화 된다. T _state;
import 'package:class_riverpod_mvvm/models/post.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../repository/post_repository.dart';

// 외부에서 접근하는 상태 변수는 state 된다 ---> T 제네릭이기 때문에 실제 값은 Post 객체 이다.
class PostDetailViewModel extends StateNotifier<AsyncValue<Post>> {
  final PostRepository _postRepository;
  final int postId;

  // AsyncValue 비동기 통신 (통신을 할때 ) 3가지 상태를 구분 짓어서 화면을 구성하는데 매우 편리하다.
  // 1 - 로딩, 2 - 데이터, 3 오류
  PostDetailViewModel(this._postRepository, this.postId)
      : super(AsyncValue.loading()) {
    // 객체 생성시에 비즈니스 로직 호출
    fetchPostGetById();
  }
  
  // 특정 게시글 요청 기능 
  Future<void> fetchPostGetById() async {
    try {
      // 응답 받은 post 객체 
      final post = await _postRepository.fetchPostById(postId);
      state = AsyncValue.data(post);
    } catch (e, stackTrace) {
      // e : 오류 메세지
      // stackTrace : 개발 시점에 어디서 오류가 발생 했는지 추적 계층 구조를 던져 준다.
      state = AsyncValue.error(2, stackTrace);
      throw Exception('통신중 오류 발생 $e');
    }
  }
}

AsyncValue를 사용하면 비동기 상태를 효율적으로 관리할 수 있는 여러 장점이 있다. AsyncValue는 비동기 작업의 세 가지 주요 상태(로딩, 성공, 오류)를 쉽게 표현할 수 있는 타입으로, 비동기 작업과 관련된 UI를 구현할 때 유용하다. 즉, 데이터의 상태와 화면에 보여줄 UI를 좀 더 쉽게 처리할 수 있다. 비동기 상태(로딩 중, 성공, 오류)에 따라 적절한 UI를 작성하기 쉽다.

 

 

postState.when(
  loading: () => CircularProgressIndicator(),
  data: (post) => Text(post.title),
  error: (e, stack) => Text('오류 발생: $e'),
);
728x90