패키지, 저장소 및 앱 카테고리 검색

패키지 상세v2.0.0

scoped_model

모든 자식에게 반응형 모델을 전달하는 위젯

AndroidiOSWebmacOSWindowsLinux
30일 다운로드
58.2만
좋아요
285
Pub 점수
150

패키지 설치

flutter pub add scoped_model

패키지 개요

공개 정보를 바탕으로 생성한 선택 가이드입니다.

Scoped Model은 Flutter용 가벼운 상태 관리 솔루션으로, 위젯 트리 전체에서 반응형 모델 공유를 가능하게 합니다. 모델 객체를 위젯 계층 구조 아래로 전달하는 간단한 방법을 제공하여 자식 위젯이 모델에 반응적으로 액세스하고 업데이트할 수 있도록 합니다. 이 패키지는 스코프 기반 접근 방식을 사용하여 모델이 변경될 때 관련된 위젯만 다시 빌드되도록 보장함으로써 성능을 향상시킵니다. Provider나 Bloc과 같은 완전한 상태 관리 솔루션이 과도할 수 있는 소규모부터 중간 규모의 앱에 적합합니다. 모든 주요 플랫폼을 지원하며 기존 Flutter 프로젝트에 원활하게 통합됩니다.

사용 사례

  • 작은 앱에서의 간단한 상태 관리
  • 여러 위젯 간에 데이터 공유
  • 모델 변경에 따른 반응형 UI 업데이트
  • 폼 상태 관리
  • 테마 또는 사용자 선호 사항 구현

주요 기능

  • 반응형 모델 전파
  • 최소한의 보일러플레이트
  • 크로스 플랫폼 지원
  • 기존 코드와의 간편한 통합
  • 모델 변경 시 위젯 자동 재구성

적합한 대상

  • 초보자 플러터 개발자
  • 경량 상태 요구 사항
  • Prototyping
  • 중등도 상태 복잡성의 앱
  • 무거운 상태 관리 프레임워크를 피하는 프로젝트

고려 사항

  • 대규모 애플리케이션에는 적합하지 않음
  • 제한된 내장 디버깅 도구
  • Riverpod과 같은 고급 솔루션보다 유연성이 낮음
  • 복잡한 상태 전이의 수동 처리
  • 모델 업데이트에 내장된 오류 처리 없음

원본 README

연결된 소스 저장소의 README 원문 스냅샷입니다. 최신 내용은 저장소에서 확인하세요.

scoped_model

Build Status codecov

A set of utilities that allow you to easily pass a data Model from a parent Widget down to its descendants. In addition, it also rebuilds all of the children that use the model when the model is updated. This library was originally extracted from the Fuchsia codebase.

This Library provides three main classes:

  • The Model class. You will extend this class to create your own Models, such as SearchModel or UserModel. You can listen to Models for changes!
  • The ScopedModel Widget. If you need to pass a Model deep down your Widget hierarchy, you can wrap your Model in a ScopedModel Widget. This will make the Model available to all descendant Widgets.
  • The ScopedModelDescendant Widget. Use this Widget to find the appropriate ScopedModel in the Widget tree. It will automatically rebuild whenever the Model notifies that change has taken place.

This library is built upon several features of Flutter:

  • The Model class implements the Listenable interface
    • AnimationController and TextEditingController are also Listenables
  • The Model is passed down the Widget tree using an InheritedWidget. When an InheritedWidget is rebuilt, it will surgically rebuild all of the Widgets that depend on its data. No need to manage subscriptions!
  • It uses the AnimatedBuilder Widget under the hood to listen to the Model and rebuild the InheritedWidget when the model changes.

Examples

  • Counter App - Introduction to the tools provided by Scoped Model.
  • Todo App - Shows how to write a Todo app with persistence and tests.

Usage

Let's demo the basic usage with the all-time favorite: A counter example!

// Start by creating a class that holds some view the app's state. In
// our example, we'll have a simple counter that starts at 0 can be 
// incremented.
//
// Note: It must extend from Model.  
class CounterModel extends Model {
  int _counter = 0;

  int get counter => _counter;

  void increment() {
    // First, increment the counter
    _counter++;
    
    // Then notify all the listeners.
    notifyListeners();
  }
}

// Create our App, which will provide the `CounterModel` to 
// all children that require it! 
class CounterApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // First, create a `ScopedModel` widget. This will provide 
    // the `model` to the children that request it. 
    return new ScopedModel<CounterModel>(
      model: new CounterModel(),
      child: new Column(children: [
        // Create a ScopedModelDescendant. This widget will get the
        // CounterModel from the nearest ScopedModel<CounterModel>. 
        // It will hand that model to our builder method, and rebuild 
        // any time the CounterModel changes (i.e. after we 
        // `notifyListeners` in the Model). 
        new ScopedModelDescendant<CounterModel>(
          builder: (context, child, model) => new Text('${model.counter}'),
        ),
        new Text("Another widget that doesn't depend on the CounterModel")
      ])
    );
  }
}

Finding the Model

There are two ways to find the Model provided by the ScopedModel Widget.

  1. Use the ScopedModelDescendant Widget. It will find the Model and run the builder function whenever the Model notifies the listeners.
  2. Use the ScopedModel.of static method directly. To make this method more readable for frequent access, you can consider adding your own of method to your own Model classes like so:
class CounterModel extends Model {
  // ...
 
  /// Wraps [ScopedModel.of] for this [Model].
  static CounterModel of(BuildContext context) =>
      ScopedModel.of<CounterModel>(context);
}

Listening to multiple Models in a build function

In many cases, it makes sense to split your Models apart into logical components by functionality. For example, rather than having an AppModel that contains all of your application logic, it can often make more sense to split models apart into a UserModel, a SearchModel and a ProductModel, for example.

However, if you need to display information from two of these models in a single Widget, you might be wondering how to achieve that! To do so, you have two options:

  1. Use multiple ScopedModelDescendant Widgets
  2. Use multiple ScopedModel.of calls. No need to manage subscriptions, Flutter takes care of all of that through the magic of InheritedWidgets.
class CombinedWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final username =
      ScopedModel.of<UserModel>(context, rebuildOnChange: true).username;
    final counter =
      ScopedModel.of<CounterModel>(context, rebuildOnChange: true).counter;

    return Text('$username tapped the button $counter times');
  }
}

Contributors

카테고리

소스 저장소

이 패키지를 사용하는 프로젝트