Flutter控制器管理插件controller的使用

发布于 1周前 作者 zlyuanteng 来自 Flutter

Flutter控制器管理插件controller的使用

Controller 插件介绍

Controller 是是一个库,它使您能够使用 Shelf 编写 HTTP 请求处理器。

功能

  • 请求映射
  • 验证
  • 安全性

开始使用

pubspec.yaml 中添加 controller 库:

dependencies:
  controller: ^0.1.10+1
  json_annotation: ^4.8.0

dev_dependencies:
  build_runner: ^2.3.3
  controller_generator: ^0.1.8
  json_serializable: ^6.6.1

使用示例

  1. 在处理请求的类上添加 @controller 注解。
  2. 标注处理方法的 HTTP 动词(如 @Get, @Put, @Delete 等)。
  3. 使用 @body 来反序列化 JSON 体到对象。
  4. 前缀路径参数时使用冒号。
import 'package:controller/controller.dart';
import 'package:shelf/shelf.dart';

part 'todo_controller.g.dart';

@controller
class TodoController {
  @Post('/todos')
  Future<Response> addTodo(@body Todo todo) {
    // 实现代码
  }

  @Get('/todos/:id')
  Future<Response> getTodo(String id) {
    // 实现代码
  }
}

请求体

  1. 将映射到请求体的类标注为 @validatable
  2. 标注字段以添加验证元数据。
  3. 添加一个 fromJson() 工厂方法。
import 'package:controller/controller.dart';
import 'package:json_annotation/json_annotation.dart';

part 'todo.g.dart';

@validatable
@JsonSerializable(createToJson: false)
class Todo {
  @notEmpty
  final String id;
  @notEmpty
  final String description;

  Todo({
    required this.id,
    required this.description,
  });

  factory Todo.fromJson(Map<String, dynamic> json) => _$TodoFromJson(json);
}

验证

  1. 验证元数据可以添加到请求体和控制器参数上。
  2. 内置可用的验证器包括:
    • @Min(value)@Max(value)
    • @Length(min, max)
    • @notEmpty
    • @Regex(pattern, description)
    • @Unique(existsPredicate)

返回响应

  1. 您可以返回 Shelf Response 对象。
  2. 当返回具有 toJson 方法的对象时,会返回一个带有 JSON 作为主体的 200 OK 响应。
import 'package:controller/controller.dart';
import 'package:shelf/shelf.dart';
import 'package:json_annotation/json_annotation.dart';

part 'todo_controller.g.dart';

@controller
class TodoController {
  @Post('/todos')
  // 返回 Future&lt;void&gt; 将返回一个空的 `200 OK ` 响应。
  Future<void> addTodo(@body Todo todo) {
    // 实现代码
  }

  @Get('/todos/:id')
  // 返回 Future&lt;A&gt; 将调用 A.toJson() 并返回一个带有 JSON 的主体的 ` 200 OK ` 响应。
  Future<Todo> getTodo(String id) {
    // 实现代码
  }
}

@JsonSerializable()
class Todo {
  @notEmpty
  final String id;
  @notEmpty
  final String description;

  Todo({
    required this.id,
    required this.description,
  });

  factory Todo.fromJson(Map<String, dynamic> json) => _$TodoFromJson(json);

  Map<String, dynamic> toJson() => _$TodoToJson(this);
}

安全性

  1. 向您想要保护的安全端点添加 @Secured 注解。
  2. @Secured 接受一个参数,该参数是请求必须遵守的条件。
  3. 您可以使用现成的条件或编写自己的条件。
import 'package:controller/controller.dart';
import 'package:shelf/shelf.dart';

part 'todo_controller.g.dart';

@controller
class TodoController {
  @Post('/todos')
  // 检查用户是否具有“role”声明且值为“todo-editor”
  @Secured(HasClaim('role', 'todo-editor'))
  Future<Response> addTodo(@body Todo todo) {
    // 实现代码
  }

  @Get('/todos/:id')
  // 自定义条件定义如下
  @Secured(IsTodoOwner())
  Future<Response> getTodo(String id) {
    // 实现代码
  }
}

class IsTodoOwner extends SecurityCondition {
  const IsTodoOwner();

  @override
  Future<bool> evaluate(Map<String, dynamic> claims, // 找到在令牌或用户数据库中的声明
      Map<String, String> headers, // 请求头和参数
      ) async {
    final userId = claims['userId'];
    // 当 true 时,用户允许访问端点
    return userId != null && headers['id'].startsWith(userId);
  }
}

设置服务器

运行 dart run build_runner build 生成分发器构建者和验证器。

创建请求分发器并将其与 Shelf 连接起来:

import 'package:controller/controller.dart';
import 'package:shelf/shelf.dart';
import 'package:shelf/shelf_io.dart';
import 'todo/todo_controller.dart';

void main() async {
  final todoController = TodoController();

  // 只有当您有安全控制器时才需要此参数
  final security = JwtSecurity(
    issuerUri: Uri.parse('https://issuer.uri.goes.here'),
    clientId: 'your-applications-client-id',
  );

  final dispatcher = createRequestDispatcher([
    // 只有带有 @Secured 方法的控制器才会接受安全参数
    TodoController$DispatcherBuilder(todoController, security),
  ]);
  final handler = Pipeline().addHandler(dispatcher);
  final server = await serve(handler, '0.0.0.0', 8080);
}

更多关于Flutter控制器管理插件controller的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter控制器管理插件controller的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter中,控制器管理插件(如providerget_itriverpod等)常用于管理应用状态,特别是跨多个小部件(widgets)共享状态时。虽然Flutter本身没有一个直接叫做“controller管理插件”的官方插件,但我们可以使用provider包作为一个常见的例子来展示如何管理控制器(controllers)。

以下是一个使用provider包管理Flutter控制器的简单示例。在这个例子中,我们将创建一个简单的计数器应用,并使用ChangeNotifierProvider来管理计数器的状态。

1. 添加依赖

首先,在你的pubspec.yaml文件中添加provider依赖:

dependencies:
  flutter:
    sdk: flutter
  provider: ^6.0.0  # 请检查最新版本号

然后运行flutter pub get来安装依赖。

2. 创建计数器控制器

创建一个新的Dart文件(例如counter_controller.dart),用于定义我们的计数器控制器:

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

class CounterController with ChangeNotifier {
  int _count = 0;

  int get count => _count;

  void increment() {
    _count++;
    notifyListeners();
  }

  void decrement() {
    _count--;
    notifyListeners();
  }
}

3. 使用ChangeNotifierProvider

在你的主应用文件(例如main.dart)中,使用ChangeNotifierProvider来提供计数器控制器,并在UI中使用它:

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'counter_controller.dart';

void main() {
  runApp(
    MultiProvider(
      providers: [
        ChangeNotifierProvider(create: (_) => CounterController()),
      ],
      child: MyApp(),
    ),
  );
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final counterController = Provider.of<CounterController>(context);

    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter Counter'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '${counterController.count}',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          counterController.increment();
        },
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
      floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
    );
  }
}

4. 扩展功能(可选)

你可以根据需要扩展功能,比如添加一个减少按钮:

// 在MyHomePage的Scaffold内添加另一个FloatingActionButton
floatingActionButton: Row(
  mainAxisAlignment: MainAxisAlignment.end,
  children: <Widget>[
    FloatingActionButton(
      onPressed: () {
        counterController.decrement();
      },
      tooltip: 'Decrement',
      child: Icon(Icons.remove),
    ),
    SizedBox(width: 10), // 添加一些间距
    FloatingActionButton(
      onPressed: () {
        counterController.increment();
      },
      tooltip: 'Increment',
      child: Icon(Icons.add),
    ),
  ],
),

总结

以上代码展示了如何使用provider包来管理Flutter中的控制器。ChangeNotifierProvider用于创建和提供CounterController实例,而小部件则通过Provider.of<CounterController>(context)来访问这个实例。这种方法使得状态管理更加集中和易于维护,特别是在大型应用中。

回到顶部