如何监听 Flutter 的 BuildContext.select() 的 class 变化?

How to listen to a class change on Flutter's BuildContext.select()?

我刚接触Flutter,一直在尝试使用Provider包来处理状态管理。 是否可以使用 context.select()?

来监听整个 class 的变化

简化代码如下。 我知道这些值在幕后发生变化,但并未反映在 UI.

我也知道,如果我在 class 上听每个单独的值,它会反映出来。但我一直在寻找一种方法来获得整个 class 的变化。

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final WageValues wageValues = context.select<ValuesModel, WageValues>(
      (values) => values.wageValues,
    );

    return Column(
      children: [
        Text('Wage: ${roundToDecimals(wageValues.wage)}'),
        Text('Insurance Percent: ${wageValues.insurancePercent}'),
        Text('Insurance Sum: ${roundToDecimals(wageValues.insuranceSum)}'),
        Text('Wage Total: ${roundToDecimals(wageValues.wageTotal)}'),
        const WageForm(),
      ],
    );
  }
}
class WageValues {
  double wage = 12;
  int insurancePercent = 30;

  double get insuranceSum => wage * insurancePercent * 0.01;
  double get wageTotal => wage + insuranceSum;
}

class ValuesModel extends ChangeNotifier {
  final WageValues _wageValues = WageValues();

  WageValues get wageValues => _wageValues;

  void setWage(double wage) {
    _wageValues.wage = wage;
    notifyListeners();
  }

  void setInsurancePercent(int insurancePercent) {
    _wageValues.insurancePercent = insurancePercent;
    notifyListeners();
  }
}

我正在为这段代码使用 Get 包而不是 Provider 包:

home_page.dart

import 'dart:math';

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:getx_obs_class/src/controllers/checker_controller.dart';

class HomePage extends StatelessWidget {
  /* ---------------------------------------------------------------------------- */
  const HomePage({Key key}) : super(key: key);
  /* ---------------------------------------------------------------------------- */
  @override
  Widget build(BuildContext context) {
    var _rnd = Random();
    final _wv = valuesModel.wageValues;

    return Scaffold(
      body: SafeArea(
        child: Padding(
          padding: const EdgeInsets.all(10),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Obx(() => Text('Wage: ${_wv.wage.toStringAsFixed(2)}')),
              Obx(() => Text('Insurance Percent: ${_wv.insurancePercent}%')),
              Obx(() => Text('Insurance Sum: ${_wv.insuranceSum.toStringAsFixed(2)}')),
              Obx(() => Text('Wage Total: ${_wv.wageTotal.toStringAsFixed(2)}')),
            ],
          ),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.track_changes),
        onPressed: () {
          valuesModel
          ..setWage(_rnd.nextDouble() * 100)
          ..setInsurancePercent(_rnd.nextInt(100));
          print('$${_wv.wage} : ${_wv.insurancePercent}%');
        },
      ),
    );
  }
}

checker_controller.dart

import 'package:get/get.dart';


class WageValues extends GetxController {
  var wage = 12.0.obs;
  var insurancePercent = 30.obs;

  double get insuranceSum => wage * insurancePercent.value * 0.01;
  double get wageTotal => wage.value + insuranceSum;
}

class ValuesModel {
  final WageValues _wageValues = Get.put(WageValues());

  WageValues get wageValues => _wageValues;

  void setWage(double wage) => _wageValues.wage.value = wage;
  void setInsurancePercent(int insurancePercent) => _wageValues.insurancePercent.value = insurancePercent;
}


final valuesModel = ValuesModel();