我正在try 创建一个通用的使用者小部件,以便于将ViewModel传递给它的子级.因此,我有两个函数.一个在初始化ViewModel之后具有函数(T),另一个用于将模型传递给子Widget.

泛型类中是ChangeNotifier的子类,在我想要在两个函数中发送T值之前,它工作得很好.

然后,我得到以下错误:

type '(OnBoardingViewModel) => Null' is not a subtype of type '(ChangeNotifier) => void'

type '(BuildContext, OnBoardingViewModel, Widget) => Scaffold' is not a subtype of type '(BuildContext, ChangeNotifier, Widget) => Widget'

但是,当我将扩展类型从ChangeNotifier更改为OnBoardingViewModel时,一切工作正常.

can someone help me 和 or explain why this ain't working??

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

class StateFullConsumerWidget<T extends ChangeNotifier> extends StatefulWidget{

  StateFullConsumerWidget({@required this.builder,Key key,this.onPostViewModelInit,this.child}) : super(key : key);

  final Widget Function(BuildContext context, ChangeNotifier value, Widget child) builder;
  final Widget child;

  final void Function(T) onPostViewModelInit;

  @override
  _StateFullConsumerWidgetState<T> createState() => _StateFullConsumerWidgetState<T>();
}

class _StateFullConsumerWidgetState<T extends ChangeNotifier> extends State<StateFullConsumerWidget>{
  T _viewModel;
  @override
  void initState() {
    // assign the model once when state is initialised
    _viewModel = GetIt.instance.get<T>();
    widget.onPostViewModelInit(_viewModel);


    super.initState();
  }
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider<T>(
      builder: (context) => _viewModel,
      child: Consumer<T>(
        builder: widget.builder,
        child: widget.child,
      ),
    );
  }

}

我的小部件

StateFullConsumerWidget<OnBoardingViewModel>(
      onPostViewModelInit: (viewModel){
        buildIntroList(viewModel);
        viewModel.maxPages = _introWidgetsList.length;
      },
      builder: (context,viewModel,child) {
        return Scaffold(
          key: widget.scaffoldKey,
          body: SafeArea(
            child: Container(),
            ),
          ),
        );
      },
    );

我的视图模型

import 'package:flutter/material.dart';

class OnBoardingViewModel extends ChangeNotifier{

  OnBoardingViewModel(){

  }
}

推荐答案

您使用泛型类型T的方式是不完整的.代码中编写的StateFullConsumerWidget_StateFullConsumerWidgetState类之间的关系是这样的:StateFullConsumerWidget使用与其自身相同的T类型参数创建其状态,因此小部件知道该状态使用与其相同的泛型类型.不过,从_StateFullConsumerWidgetState的Angular 来看,该类声明如下:

class _StateFullConsumerWidgetState<T extends ChangeNotifier> 
    extends State<StateFullConsumerWidget>

问题是STATE类使用的是StateFullConsumerWidget的一般形式,因此_StateFullConsumerWidgetState作为类型参数接收的TStateFullConsumerWidget使用的T之间没有显式关系.DART不知道如何协调这种模棱两可的关系,因此它默认为类型约束允许的最低公分母,即ChangeNotifier.

因此,当您try 将T视为OnBoardingViewModel时,DART会抛出一个错误,因为据State类所知,父小部件的TChangeNotifier,而不是OnBoardingViewModel.

您可以通过在声明状态类时传递类型参数来解决此问题:

class _StateFullConsumerWidgetState<T extends ChangeNotifier> 
    extends State<StateFullConsumerWidget<T>>

Dart相关问答推荐

Dart中的运算符(){…}做什么?

Dart 可空记录与模式匹配:(String, int)?类型的匹配值无法分配给所需类型(Object?, Object?)

Dart,后面带感叹号的标识符

Flutter Drawer 作为单独的小部件不允许修改宽度

dart:js 和 js 包有什么区别?

如何从 Flutter App 连接 Ms SQL?

如何在Flatter中zoom 两个谷歌 map 标记

如何防止键盘在Flutter中按提交键时失效?

如何使我的Flitter应用程序的导航抽屉(Navigation Drawer)透明?

Dart - 一个 dart 项目如何在不使用 pub 的情况下从另一个 dart 项目导入代码?

Flutter:如何正确实现 FlutterError.OnError

Flutter 屏幕尺寸计算

如何判断一个字符串是否可以是 json.decode

Dart 工厂构造函数 - 它与const构造函数有何不同

从 Dart 调用 javascript

在 Dart 中,List.from 和 .of 以及 Map.from 和 .of 有什么区别?

如何在 Dart 中逐个字符地迭代字符串?

是否可以在 Dart 中的一行上初始化列表?

包裹构造函数参数的花括号代表什么?

Dart,如何在你自己的函数中创建一个返回的future ?