scoped_model 0.2.0

  • README.md
  • CHANGELOG.md
  • Example
  • Installing
  • Versions
  • 93

scoped_model

Build Status codecov

A set of utilities that allow you to easily pass a data Model from a parent Widget down to it's descendants. In addition, it also re-renders all of the children who use the model when the model is updated.

Besides a couple of tests and a bit of documentation, this is not my work / idea. It's a simple extraction of the Model classes from Fuchsia's core Widgets, presented as a standalone Flutter Plugin for independent use so we can evaluate this architecture pattern more easily as a community.

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.toString()),
              ),
        new Text("Another widget that doesn't depend on the CounterModel")
      ])
    );
  }
}

Contributors

Changelog

0.2.0

  • Thanks to @passsy for the contributions!
  • Model cannot be null
  • Model now implements Listenable
  • Improve Docs
  • Improve tests

0.1.1

  • Move to github

0.1.0

  • Initial version

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:scoped_model/scoped_model.dart';

void main() {
  runApp(new MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // At the top level of our app, we'll, create a ScopedModel Widget. This
    // will provide the CounterModel to all children in the app that request it
    // using a ScopedModelDescendant.
    return new ScopedModel<CounterModel>(
      model: new CounterModel(),
      child: new MaterialApp(
        title: 'Flutter Demo',
        theme: new ThemeData(
          primarySwatch: Colors.green,
        ),
        home: new CounterHome('Scoped Model Demo'),
      ),
    );
  }
}

// Start by creating a class that has a counter and a method to increment it.
//
// 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();
  }
}

class CounterHome extends StatelessWidget {
  final String title;

  CounterHome(this.title);

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text(title),
      ),
      body: new Center(
        child: new Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            new Text(
              'You have pushed the button this many times:',
            ),
            // Create a ScopedModelDescendant. This widget will get the
            // CounterModel from the nearest parent ScopedModel<CounterModel>.
            // It will hand that CounterModel 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.toString(),
                  style: Theme.of(context).textTheme.display1),
            ),
          ],
        ),
      ),
      // Use the ScopedModelDescendant again in order to use the increment
      // method from the CounterModel
      floatingActionButton: new ScopedModelDescendant<CounterModel>(
        builder: (context, child, model) => new FloatingActionButton(
              onPressed: model.increment,
              tooltip: 'Increment',
              child: new Icon(Icons.add),
            ),
      ),
    );
  }
}

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  scoped_model: "^0.2.0"

2. Install it

You can install packages from the command line:

with Flutter:


$ flutter packages get

Alternatively, your editor might support packages get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:scoped_model/scoped_model.dart';
        
Version Uploaded Documentation Archive
0.2.0 Jan 4, 2018 Go to the documentation of scoped_model 0.2.0 Download scoped_model 0.2.0 archive
0.1.1 Nov 25, 2017 Go to the documentation of scoped_model 0.1.1 Download scoped_model 0.1.1 archive
0.1.0 Aug 17, 2017 Go to the documentation of scoped_model 0.1.0 Download scoped_model 0.1.0 archive

Analysis

We analyzed this package on Apr 23, 2018, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.0.0-dev.49.0
  • pana: 0.10.6
  • Flutter: 0.3.2

Scores

Popularity:
Describes how popular the package is relative to other packages. [more]
86 / 100
Health:
Code health derived from static analysis. [more]
99 / 100
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
100 / 100
Overall score:
Weighted score of the above. [more]
93
Learn more about scoring.

Platforms

Detected platforms: Flutter

References Flutter, and has no conflicting libraries.

Suggestions

  • Package is pre-v1 release.

    While there is nothing inherently wrong with versions of 0.*.*, it usually means that the author is still experimenting with the general direction API.

  • Fix analysis and formatting issues.

    Analysis or formatting checks reported 2 hints.

    Run flutter format to format lib/generated/i18n.dart.

Dependencies

Package Constraint Resolved Available
Direct dependencies
flutter 0.0.0
Transitive dependencies
collection 1.14.6 1.14.9
meta 1.1.2
sky_engine 0.0.99
typed_data 1.1.5
vector_math 2.0.6
Dev dependencies
flutter_test