Browse Source

update to dartin

ditclear 7 years ago
parent
commit
5a4df5529b

+ 24 - 19
README.md

@@ -2,25 +2,30 @@
 
 Build MVVM App for Android and IOS with Flutter。
 
-项目结构类似于[MVVM-Android](https://github.com/ditclear/MVVM-Android)。
+The Structure seems like [MVVM-Android](https://github.com/ditclear/MVVM-Android)。
 
 ![](architecture.png)
 
-##### 下载体验
+##### DownLoad
 
 ![](android.png)
 
 #### dependencies
 
-- [dio](https://github.com/flutterchina/dio) : 网络请求
-- [rxdart](https://github.com/ReactiveX/rxdart):响应式编程
-- [flutter-provide](https://github.com/google/flutter-provide):通知ui更新数据
+- [dio](https://github.com/flutterchina/dio) : netword 
+- [rxdart](https://github.com/ReactiveX/rxdart):reactive programming
+- [flutter-provide](https://github.com/google/flutter-provide):state managing
+- [dartin](https://github.com/ditclear/dartin): dependency injection
+
+> PS:each layer connected by rx, use responsive thinking and rxdart operators for logical processing.Finally, update the view with [flutter-provide](https://github.com/google/flutter-provide).
+
+### ScreenShot
+
+![](screenshot.png)![](ios.png)
+
 
-> 思想:M-V-VM各层直接通过rx衔接,配合响应式的思想和rxdart的操作符进行逻辑处理,最后通过provide来更新视图。
 
-### 截图
 
-![](screenshot.png)
 
 #### Code
 
@@ -42,20 +47,20 @@ class GithubRepo {
 }
 //viewmodel
 class HomeViewModel extends ChangeNotifier {
-  final GithubRepo _repo; //数据仓库
-  String username = ""; //账号
-  String password = ""; //密码
-  bool _loading = false; // 加载中
-  String _response = ""; //响应数据
+  final GithubRepo _repo; 
+  String username = ""; 
+  String password = ""; 
+  bool _loading = false; 
+  String _response = ""; 
   //...
   HomeViewModel(this._repo);
 
-  /**
-   * 调用model层的方法进行登录
-   * doOnData : 请求成功时,处理响应数据
-   * doOnError : 请求失败时,处理错误
-   * doOnListen : 开始时loading为true,通知ui更新
-   * doOnDone : 结束时loading为false,通知ui更新
+   /**
+   * call the model layer 's method to login
+   * doOnData : handle response when success
+   * doOnError : handle error when failure
+   * doOnListen : show loading when listen start
+   * doOnDone : hide loading when complete
    */
   Observable login() => _repo
       .login(username, password)

BIN
ios.png


+ 3 - 2
lib/di/app_module.dart

@@ -1,13 +1,14 @@
 import 'package:mvvm_flutter/model/remote.dart';
 import 'package:mvvm_flutter/model/repository.dart';
 import 'package:mvvm_flutter/viewmodel/home_provide.dart';
+import 'package:dartin/dartin.dart';
 
-import 'dartin.dart';
+const testScope = DartInScope('test');
 
 final viewModelModule = Module([
   factory<HomeProvide>(({params}) => HomeProvide(params.get(0), get<GithubRepo>())),
 ])
-  ..addOthers(DartInScope('test'), [
+  ..addOthers(testScope, [
     ///other scope
 //  factory<HomeProvide>(({params}) => HomeProvide(params.get(0), get<GithubRepo>())),
   ]);

+ 0 - 262
lib/di/dartin.dart

@@ -1,262 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/// A [DartInScope] provides a separate type-space for a provider, thus
-/// allowing more than one provider of the same type.
-///
-/// This should always be initialized as a static const and passed around.
-/// The name is only used for descriptive purposes.
-class DartInScope {
-  final String _name;
-
-  /// Constructor
-  const DartInScope(this._name);
-
-  @override
-  String toString() {
-    return "Scope ('$_name')";
-  }
-}
-
-/// DartIns are the container to provide dependencies.
-///
-/// DartIns can be added to using either convenience functions such as
-/// [provideValue] or by passing in DartIns.
-class DartIns {
-  // The DartIn for each given [Type] should return that type, but we can't
-  // enforce that here directly. We can use APIs to make sure it's type-safe.
-  final Map<DartInScope, Map<Type, DartIn<dynamic>>> _providers = {};
-
-  /// Creates a new empty provider.
-  DartIns();
-
-  /// The default scope in which any type not with a defined scope resides.
-  static const DartInScope defaultScope = DartInScope('_default');
-
-  /// Creates a provider with the included providers.
-  ///
-  /// If a scope is provided, the values will be under that scope.
-  factory DartIns.withDartIns(Map<Type, DartIn<dynamic>> providers, {DartInScope scope}) => DartIns()..provideAll(providers, scope: scope);
-
-  /// Add a provider for a single type.
-  ///
-  /// Will override any existing provider of that type in this node with the
-  /// given scope. If no [scope] is passed in, the default one will be used.
-  void provide<T>(DartIn<T> provider, {DartInScope scope}) {
-    // This should never happen.
-//    assert(provider.type == T);
-    _providersForScope(scope)[provider.type] = provider;
-  }
-
-  /// Provide many providers at once.
-  ///
-  /// Prefer using [provide] and [provideFrom] because that catches type
-  /// errors at compile-time.
-  void provideAll(Map<Type, DartIn> providers, {DartInScope scope}) {
-    for (var entry in providers.entries) {
-      if (entry.key != entry.value.type) {
-        if (entry.value.type == dynamic) {
-          throw ArgumentError('Not able to infer the type of provider for'
-              ' ${entry.key} automatically. Add type argument to provider.');
-        }
-        throw ArgumentError('Type mismatch between ${entry.key} and provider '
-            'of ${entry.value.type}.');
-      }
-    }
-
-    _providersForScope(scope).addAll(providers);
-  }
-
-  /// Add in all the providers from another DartIns.
-  void provideFrom(DartIns other) {
-    for (final scope in other._providers.keys) {
-      provideAll(other._providersForScope(scope), scope: scope);
-    }
-  }
-
-  /// Add dartin in different scopes from [Module]
-  void provideFromModule(Module module) {
-    final tempMap = module._providerIns;
-    for (var scope in tempMap.keys) {
-      for (var dartin in tempMap[scope]) {
-        provide(dartin, scope: scope);
-      }
-    }
-  }
-
-  /// Syntactic sugar around adding a value based provider.
-  ///
-  ///  If no [scope] is passed in, the default one will be used.
-  void provideValue<T>(T value, {DartInScope scope}) {
-    provide(DartIn._value(value), scope: scope);
-  }
-
-  /// get DartIn from Type,maybe null
-  DartIn<T> getFromType<T>({DartInScope scope}) {
-    return _providersForScope(scope)[T];
-  }
-
-  /// find T from [_providers] , may be null
-  T value<T>({DartInScope scope, List params}) {
-    return getFromType<T>(scope: scope)?.get(params: params);
-  }
-
-  Map<Type, DartIn<dynamic>> _providersForScope(scope) => _providers[scope ?? defaultScope] ??= {};
-}
-
-/// A DartIn provides a value on request.
-///
-/// When a DartIn is instantiated within a [providers.provide] call, the type
-/// can be inferred and therefore the type can be ommited, but otherwise,
-/// [T] is required.
-///
-/// DartIn should be implemented and not extended.
-abstract class DartIn<T> {
-  /// Returns the value provided by the provider.
-  ///
-  /// Because providers could potentially initialize the value each time [get]
-  /// is called, this should be called as infrequently as possible.
-  T get({List params});
-
-  /// The type that is provided by the provider.
-  Type get type;
-
-  /// Creates a provider with the value provided to it.
-  factory DartIn._value(T value) => _ValueDartIn(value);
-
-  /// Creates a provider which will initialize using the [_DartInFunction]
-  /// the first time the value is requested.
-  ///
-  /// The context can be used to obtain other values from the provider. However,
-  /// care should be taken with this to not have circular dependencies.
-  factory DartIn._lazy(_DartInFunction<T> function) => _LazyDartIn<T>(function);
-
-  /// Creates a provider that provides a new value for each
-  /// requestor of the value.
-  factory DartIn._withFactory(_DartInFunction<T> function) => _FactoryDartIn<T>(function);
-}
-
-/// Base mixin for providers.
-abstract class _TypedDartIn<T> implements DartIn<T> {
-  /// The type of the provider
-  @override
-  Type get type => T;
-}
-
-/// Contains a value which will never be disposed.
-class _ValueDartIn<T> extends _TypedDartIn<T> {
-  final T _value;
-
-  @override
-  T get({List params}) => _value;
-
-  _ValueDartIn(this._value);
-}
-
-/// Function that returns an instance of T when called.
-typedef _DartInFunction<T> = T Function({_ParameterList params});
-
-/// Is initialized on demand, and disposed when no longer needed
-/// if [dispose] is set to true.
-/// When obtained statically, the value will never be disposed.
-class _LazyDartIn<T> with _TypedDartIn<T> {
-  final _DartInFunction<T> _initalizer;
-
-  T _value;
-
-  _LazyDartIn(this._initalizer);
-
-  @override
-  T get({List params}) {
-    // Need to have a local copy for casting because
-    // dart requires it.
-    T value;
-    if (_value == null) {
-      value = _value ??= _initalizer(params: _ParameterList.parametersOf(params));
-    }
-    return _value;
-  }
-}
-
-/// A provider who's value is obtained from providerFunction for each time the
-/// value is requested.
-///
-/// This provider doesn't keep any values itself, so those values are disposed
-/// when the containing widget is disposed.
-class _FactoryDartIn<T> with _TypedDartIn<T> {
-  final _DartInFunction<T> providerFunction;
-
-  _FactoryDartIn(this.providerFunction);
-
-  @override
-  T get({List params}) => providerFunction(params: _ParameterList.parametersOf(params));
-}
-
-/// Module Definition
-class Module {
-  /// Gather dependencies & properties definitions
-  final Map<DartInScope, List<DartIn>> _providerIns = {};
-
-  /// dependencies in defaultScope
-  Module(List<DartIn> defaults) {
-    _providerIns[DartIns.defaultScope] = defaults ??= [];
-  }
-
-  /// dependencies in otherScope
-  void addOthers(DartInScope otherScope, List<DartIn> others) {
-    assert(otherScope._name != DartIns.defaultScope._name);
-    _providerIns[otherScope] = others ??= [];
-  }
-}
-
-/// List of parameter
-class _ParameterList {
-  final List<Object> params;
-
-  /**
-   * get element at given index
-   */
-  get(int i) {
-    if (params == null || i > params.length - 1 || i < 0) {
-      return null;
-    }
-    return params[i];
-  }
-
-  _ParameterList.parametersOf(this.params);
-}
-
-/// Creates a provider that provides a new value using the [_DartInFunction] for each
-/// requestor of the value.
-DartIn<T> factory<T>(_DartInFunction<T> value, {String scope}) => DartIn<T>._withFactory(value);
-
-/// Creates a provider with the value provided to it.
-DartIn<T> single<T>(T value) => DartIn<T>._value(value);
-
-/// Creates a provider which will initialize using the [_DartInFunction]
-/// the first time the value is requested.
-DartIn<T> lazy<T>(_DartInFunction<T> value) => DartIn<T>._lazy(value);
-
-/// get T  from dartIns by T.runtimeType and params
-T get<T>({String scopeName, List params}) {
-  assert(_dartIns != null, "error: please use startDartIn method first ");
-  final scope = scopeName == null ? DartIns.defaultScope : DartInScope(scopeName);
-  final result = _dartIns.value<T>(scope: scope, params: params);
-  assert(result != null, "error: not found $T in ${scope.toString()}");
-  return result;
-}
-
-/// get T  from dartIns by T.runtimeType and params
-T inject<T>({String scopeName, List params}) => get<T>(scopeName: scopeName, params: params);
-
-/// global dependencies 's container in App
-DartIns _dartIns;
-
-/// init and load dependencies to [DartIns] from modules
-startDartIn(List<Module> modules) {
-  _dartIns = DartIns();
-  for (var module in modules) {
-    _dartIns.provideFromModule(module);
-  }
-}

+ 1 - 0
lib/di/modules.dart

@@ -7,6 +7,7 @@ final Dio dio = Dio()
   ..interceptors.add(AuthInterceptor())
   ..interceptors.add(LogInterceptor(responseBody: true, requestBody: true));
 
+
 class AuthInterceptor extends Interceptor {
   @override
   onRequest(RequestOptions options) {

+ 5 - 8
lib/helper/dialog.dart

@@ -6,13 +6,12 @@ Future<T> _showAlert<T>({BuildContext context, Widget child}) => showDialog<T>(
       barrierDismissible: false,
       builder: (BuildContext context) => child,
     );
-/**
- * onlyPositive  : 只有确定按钮
- */
+
+
 Future<bool> showAlert(BuildContext context,
         {String title,
-        String negativeText = "取消",
-        String positiveText = "确定",
+        String negativeText = "Cancel",
+        String positiveText = "Confirm",
         bool onlyPositive = false}) =>
     _showAlert<bool>(
       context: context,
@@ -64,9 +63,7 @@ List<Widget> _buildAlertActions(BuildContext context, bool onlyPositive,
   }
 }
 
-/**
- * 显示loading框  , 隐藏调用 Navigator.pop(context)
- */
+
 Future _showLoadingDialog(BuildContext c, LoadingDialog loading,
         {bool cancelable = true}) =>
     showDialog(

+ 8 - 8
lib/helper/widgetutils.dart

@@ -10,23 +10,23 @@ dispatchFailure(BuildContext context, dynamic e) {
     final response = e.response;
 
     if (response?.statusCode == 401) {
-      message = "账号或密码错误";
+      message = "account or password error ";
     } else if (403 == response?.statusCode) {
-      message = "禁止访问";
+      message = "forbidden";
     } else if (404 == response?.statusCode) {
-      message = "链接错误";
+      message = "page not found";
     } else if (500 == response?.statusCode) {
-      message = "服务器内部错误";
+      message = "Server internal error";
     } else if (503 == response?.statusCode) {
-      message = "服务器升级中";
+      message = "Server Updating";
     } else if (e.error is SocketException) {
-      message = "网络未连接";
+      message = "network cannot use";
     } else {
       message = "Oops!!";
     }
   }
-  print("出错了:"+message);
-  if(context!=null) {
+  print("error :" + message);
+  if (context != null) {
     Toast.show(message, context, type: Toast.ERROR);
   }
 }

+ 4 - 1
lib/main.dart

@@ -2,10 +2,13 @@ import 'package:flutter/material.dart';
 import 'package:mvvm_flutter/view/home_page.dart';
 
 import 'di/app_module.dart';
-import 'di/dartin.dart';
+import 'package:dartin/dartin.dart';
+
 
 void main() {
+  /// DartIn start
   startDartIn(appModule);
+
   runApp(MyApp());
 }
 

+ 2 - 2
lib/view/base.dart

@@ -2,14 +2,14 @@ import 'package:flutter/material.dart';
 import 'package:provide/provide.dart';
 
 /**
- * 普通widget点击事件处理
+ * normal click event
  */
 abstract class Presenter {
   void onClick(String action);
 }
 
 /**
- * 列表Item点击事件处理
+ * ListView Item Click
  */
 abstract class ItemPresenter<T> {
   void onItemClick(String action, T item);

+ 4 - 4
lib/view/home_page.dart

@@ -1,6 +1,6 @@
+import 'package:dartin/dartin.dart';
 import 'package:flutter/cupertino.dart';
 import 'package:flutter/material.dart';
-import 'package:mvvm_flutter/di/dartin.dart';
 import 'package:mvvm_flutter/helper/dialog.dart';
 import 'package:mvvm_flutter/helper/toast.dart';
 import 'package:mvvm_flutter/helper/widgetutils.dart';
@@ -100,7 +100,7 @@ class _HomeContentState extends State<_HomeContentPage> with SingleTickerProvide
                 decoration: InputDecoration(
                   contentPadding: EdgeInsets.all(10.0),
                   icon: Icon(Icons.person),
-                  labelText: '账号',
+                  labelText: 'Account',
                 ),
                 autofocus: false,
                 onChanged: (str) => _viewModel.username = str,
@@ -111,7 +111,7 @@ class _HomeContentState extends State<_HomeContentPage> with SingleTickerProvide
                 decoration: InputDecoration(
                   contentPadding: EdgeInsets.all(10.0),
                   icon: Icon(Icons.lock),
-                  labelText: '密码',
+                  labelText: 'Password',
                 ),
                 autofocus: false,
                 onChanged: (str) => _viewModel.password = str,
@@ -168,7 +168,7 @@ class _HomeContentState extends State<_HomeContentPage> with SingleTickerProvide
       return const FittedBox(
         fit: BoxFit.scaleDown,
         child: const Text(
-          '使用GitHub账号登录',
+          'Login With Github Account',
           maxLines: 1,
           textAlign: TextAlign.center,
           overflow: TextOverflow.fade,

+ 11 - 11
lib/viewmodel/home_provide.dart

@@ -2,7 +2,6 @@ import 'dart:async';
 
 import 'package:dio/dio.dart';
 import 'package:flutter/material.dart';
-import 'package:mvvm_flutter/di/dartin.dart';
 import 'package:mvvm_flutter/model/repository.dart';
 import 'package:rxdart/rxdart.dart';
 
@@ -11,11 +10,11 @@ import 'package:rxdart/rxdart.dart';
  */
 class HomeProvide extends ChangeNotifier {
   final CompositeSubscription _subscriptions = CompositeSubscription();
-  final GithubRepo _repo; //数据仓库
-  String username = ""; //账号
-  String password = ""; //密码
-  bool _loading = false; // 加载中
-  String _response = ""; //响应数据
+  final GithubRepo _repo;
+  String username = "";
+  String password = "";
+  bool _loading = false;
+  String _response = "";
 
   final String title;
 
@@ -45,11 +44,11 @@ class HomeProvide extends ChangeNotifier {
   HomeProvide(this.title,this._repo);
 
   /**
-   * 调用model层的方法进行登录
-   * doOnData : 请求成功时,处理响应数据
-   * doOnError : 请求失败时,处理错误
-   * doOnListen : 开始时loading为true,通知ui更新
-   * doOnDone : 结束时loading为false,通知ui更新
+   * call the model layer 's method to login
+   * doOnData : handle response when success
+   * doOnError : handle error when failure
+   * doOnListen : show loading when listen start
+   * doOnDone : hide loading when complete
    */
   Observable login() => _repo
       .login(username, password)
@@ -72,6 +71,7 @@ class HomeProvide extends ChangeNotifier {
 
   }
 
+  /// add [StreamSubscription] to [_subscriptions]
   void plus(StreamSubscription s) {
     _subscriptions.add(s);
   }

+ 2 - 0
pubspec.yaml

@@ -22,6 +22,8 @@ dependencies:
   provide: ^1.0.2
   dio: 2.0.7
   rxdart: ^0.21.0
+  dartin: ^0.0.1
+
 
 dev_dependencies:
   flutter_test:

BIN
screenshot.png