{"id":18868415,"url":"https://github.com/best-flutter/puremvc","last_synced_at":"2025-06-30T23:02:15.180Z","repository":{"id":56830794,"uuid":"231046376","full_name":"best-flutter/puremvc","owner":"best-flutter","description":"flutter版本puremvc","archived":false,"fork":false,"pushed_at":"2020-01-24T03:36:59.000Z","size":99,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-05-30T16:30:37.076Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Dart","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/best-flutter.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-12-31T07:22:27.000Z","updated_at":"2020-04-16T12:33:30.000Z","dependencies_parsed_at":"2022-09-09T18:01:23.208Z","dependency_job_id":null,"html_url":"https://github.com/best-flutter/puremvc","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/best-flutter/puremvc","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/best-flutter%2Fpuremvc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/best-flutter%2Fpuremvc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/best-flutter%2Fpuremvc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/best-flutter%2Fpuremvc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/best-flutter","download_url":"https://codeload.github.com/best-flutter/puremvc/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/best-flutter%2Fpuremvc/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262863637,"owners_count":23376449,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-08T05:13:35.416Z","updated_at":"2025-06-30T23:02:14.478Z","avatar_url":"https://github.com/best-flutter.png","language":"Dart","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n    \u003ca href=\"https://travis-ci.org/best-flutter/puremvc\"\u003e\n        \u003cimg src=\"https://travis-ci.org/best-flutter/puremvc.svg?branch=master\" alt=\"Build Status\" /\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://coveralls.io/github/best-flutter/puremvc?branch=master\"\u003e\n        \u003cimg src=\"https://coveralls.io/repos/github/best-flutter/puremvc/badge.svg?branch=master\" alt=\"Coverage Status\" /\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://github.com/jzoom/puremvc/pulls\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/PRs-Welcome-brightgreen.svg\" alt=\"PRs Welcome\" /\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://pub.dartlang.org/packages/fpuremvc\"\u003e\n        \u003cimg src=\"https://img.shields.io/pub/v/fpuremvc.svg\" alt=\"pub package\" /\u003e\n    \u003c/a\u003e\n    \u003ca target=\"_blank\" href=\"https://shang.qq.com/wpa/qunwpa?idkey=a71a2504cda4cc9ace3320f2dc588bdae928abc671e903463caeb71ec9302c2c\"\u003e\u003cimg border=\"0\" src=\"https://pub.idqqimg.com/wpa/images/group.png\" alt=\"best-flutter\" title=\"best-flutter\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\n\n# puremvc\n\npuremvc for flutter\n\n页面与逻辑完全分离，页面可以不知道模型，模型可以不知道页面。\n\n\n为什么要有这个库？\n\n目前的状态管理库要么使用过于复杂，要么并不能做到模型和页面完全隔离，所以有这个库。\n\n\n\n\n## Getting Started\n\n\n#### 导入\n\n```\nimport 'package:fpuremvc/fpuremvc.dart';\n```\n\n因为这里puremvc已经被占用了，所以只能这样\n\n\n#### 流程\n\n定义一个模型，模型用于存储数据和接收dispatch的消息并处理，完成之后notify通知已经完成\n\n```\n\nclass NumberModel extends BaseModel {\n  @override\n  String get name =\u003e \"number\";\n\n  int counter = 0;\n\n  @override\n  Future setup() async {\n    await Future.delayed(new Duration(seconds: 2));\n  }\n\n  @override\n  update(String event, data) {\n    if (event == \"add\") {\n      return add();\n    }\n  }\n\n  int add() {\n    ++counter;\n    return counter;\n  }\n}\n\n\n```\n\n创建模型，一般保存为App的实例\n```\n\n\nNumberModel numberModel = new NumberModel();\n```\n\n\n\n页面使用:\n\n\n第一种：StatefulWidget\n\n```\nimport 'package:flutter/material.dart';\nimport 'package:fpuremvc/fpuremvc.dart';\n\n\n\nclass StatefulDemo extends StatefulWidget {\n  final int counter;\n\n  StatefulDemo({Key key, this.counter}) : super(key: key);\n\n  @override\n  _StatefulDemoState createState() =\u003e _StatefulDemoState();\n}\n\nclass _StatefulDemoState extends ObserverState\u003cStatefulDemo\u003e {\n  int _counter;\n\n  @override\n  void initState() {\n    _counter = widget.counter;\n    bind(\"number/add@ok\", onCounter);\n    bind(\"number/asyncAdd@ok\", onCounter);\n    /// the the lines can be replaced by  bind(\"number/*@ok\", onCounter); or just bind(\"number/*\", onCounter)\n\n\n    super.initState();\n  }\n\n  void onCounter(int counter) {\n    this._counter = counter;\n  }\n\n\n  @override\n  Widget build(BuildContext context) {\n    return Scaffold(\n      appBar: AppBar(\n        title: Text(\"StatefulDemo\"),\n      ),\n      body: Column(\n          children: \u003cWidget\u003e[\n            Text(\n              'Model is setting up,so if you click button quickly,it looks like not working',\n            ),\n            Text(\n              '$_counter',\n              style: Theme.of(context).textTheme.display1,\n            ),\n            new RaisedButton(\n              onPressed: () {\n                Navigator.pushNamed(context, \"stateless\");\n              },\n              child: new Text(\"Stateless\"),\n            ),\n\n\n            new RaisedButton(\n              onPressed: ()=\u003edispatch(\"number/add\"),\n              child: new Text(\"Sync increment\"),\n            ),\n\n            new RaisedButton(\n              onPressed: ()=\u003edispatch(\"number/asyncAdd\"),\n              child: new Text(\"Async increment\"),\n            ),\n\n\n          ],\n        ),\n\n\n    );\n  }\n}\n\n```\n\n\n第二种:通过build来创建StateLess页面\n\n\n\n```\nimport 'package:flutter/material.dart';\nimport 'package:fpuremvc/fpuremvc.dart';\n\n@immutable\nclass StatelessDemo extends StatelessWidget {\n  final int counter;\n\n  StatelessDemo({this.counter});\n\n  void _incrementCounter() {\n    dispatch(\"number/add\");\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    return Scaffold(\n      appBar: AppBar(\n        title: Text(\"StatelessDemo\"),\n      ),\n      body: Center(\n        child: Column(\n          mainAxisAlignment: MainAxisAlignment.center,\n          children: \u003cWidget\u003e[\n            Text(\n              'You have pushed the button this many times:',\n            ),\n            Text(\n              '$counter',\n              style: Theme.of(context).textTheme.display1,\n            ),\n            new RaisedButton(\n              onPressed: () {\n                Navigator.pop(context);\n              },\n              child: new Text(\"Back\"),\n            )\n          ],\n        ),\n      ),\n      floatingActionButton: FloatingActionButton(\n        onPressed: _incrementCounter,\n        tooltip: 'Increment',\n        child: Icon(Icons.add),\n      ),\n    );\n  }\n}\n\n\n```\n\n\n使用一些路由组件使得页面和模型隔离,或者全局保存这些WidgetBuilder\n```\nWidgetBuilder statelessBuilder= PureMvc.eventBuilder([\"counter\"], (c){\n    return StatelessDemo(title: 'Flutter Demo Home Page',counter: numberModel.counter,);\n});\n```\n\n```\nNavigator.push(context, new MaterialPageRoute(builder: statelessBuilder));\n```\n\n直接使用routers\n\n\n```\n\n\nMap\u003cString, WidgetBuilder\u003e routers = {\n\n  /// 定义个WidgetBuild,在监听到通知number/*@ok的时候重建， * 为通配符\n  \"stateless\": PureMvc.eventBuilder([\"number/*@ok\"], (c) {\n    return StatelessDemo(\n      counter: numberModel.counter,\n    );\n  }),\n\n    .....\n  \"stateful\": (c) {\n    return StatefulDemo(\n      counter: numberModel.counter,\n    );\n  }\n};\n\n\n```\nNavigator.pushNamed(context, \"stateful\")\n\n\n\n## 异步\n\n\n\n```\n\nclass NumberModel extends BaseModel {\n  @override\n  String get name =\u003e \"number\";\n\n  int counter = 0;\n\n  @override\n  Future setup() async {\n    await Future.delayed(new Duration(seconds: 2));\n  }\n\n  @override\n  update(String event, data) {\n    if (event == \"add\") {\n      return add();\n    } else if (event == 'asyncAdd') {\n      return asynAdd();\n    }\n  }\n\n  int add() {\n    ++counter;\n    return counter;\n  }\n\n  asynAdd() async {\n    await Future.delayed(new Duration(milliseconds: 500));\n    ++counter;\n    return counter;\n  }\n}\n`\n```\n\n\n模型中的asynAdd方法为异步方法，此时可以使用 `dispatch('number/asynAdd')` 调用,\n\n注意这里的判断\n\n```\nelse if (event == 'asyncAdd') {\n      return asynAdd();\n    }\n```\n\n\n* 当异步方法返回成功时候，将会通知事件   number/asynAdd@ok\n* 当异步方法返回失败时候，将会通知事件   number/asynAdd@fail\n* 当异步方法结束时候，将会通知事件 number/asynAdd@end\n\n\n\n\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbest-flutter%2Fpuremvc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbest-flutter%2Fpuremvc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbest-flutter%2Fpuremvc/lists"}