【问题标题】:Not able to call class method using Provider.of(context)无法使用 Provider.of(context) 调用类方法
【发布时间】:2020-09-18 21:41:30
【问题描述】:

我正在学习使用此代码使用状态管理和提供程序包。

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

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider<Data>(
      create: (context) => Data(),
      child: MaterialApp(
        home: Scaffold(
          appBar: AppBar(
            title: MyText(),
          ),
          body: Level1(),
        ),
      ),
    );
  }
}

class Level1 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      child: Level2(),
    );
  }
}

class Level2 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        MyTextField(),
        Level3(),
      ],
    );
  }
}

class Level3 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Text(Provider.of<Data>(context).data);
  }
}

class MyText extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Text(Provider.of<Data>(context).data);
  }
}

class MyTextField extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return TextField(
      onChanged: (newText) {
        print("onChanged Start");
        Provider.of<Data>(context).changeString(newText); //this line troubling me
        print("onChanged End");
      },
    );
  }
}

class Data extends ChangeNotifier {
  String data = "Some Data";

  void changeString(String newString) {
    print("changeString Start");
    print(newString + " changeString Text");
    data = newString;
    notifyListeners();
    print("changeString End");
  }
}

在运行应用程序时,AppBar Text MyText() 和 Level 3 Text Text() 工作正常。 好像我在代码中更改了data 的值并热重启了data 中更新的更改,并且也反映在了应用程序中。

我还创建了MyTextFiled(),如果发生任何更改,它应该在data 中更新,但changeString() 方法没有被第64 行的Provider.of&lt;Data&gt;(context) 调用。

这是我在 TextField 中键入“Test”时的控制台输出。

onChange Start
t
onChange Start
te
onChange Start
tes
onChange Start
test

预期是:

onChange Start
t
changeString Start
t changeString Text
changeString End
onChange End
(so on .....)

我正在使用provider: ^4.1.2,在教程(我正在关注的)中,他们使用provider: ^3.0.0+1 所以,我在第 10 行将builder 更改为create,因为它显示错误。

我的 Flutter 版本:

Flutter 1.17.0 • channel stable • https://github.com/flutter/flutter.git
Framework • revision e6b34c2b5c (4 weeks ago) • 2020-05-02 11:39:18 -0700
Engine • revision 540786dd51
Tools • Dart 2.8.1

PS:借助此示例Provider ExampleProvider.of&lt;Data&gt;(context).changeString(newText); 替换为context.read&lt;Data&gt;().changeString(newText);,我的问题得到解决

但我无法理解为什么 Provider.of(context) 不起作用但 context.read() 起作用。 请给我解释一下。

对于在这个神圣的社区提出一个愚蠢的问题,我深表歉意。 感谢您仔细聆听/阅读我的问题。

【问题讨论】:

    标签: flutter dart flutter-dependencies dart-pub flutter-provider


    【解决方案1】:

    像这样更改 TextField 的 onChanged 函数:

    class MyTextField extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return TextField(
          onChanged: (newText) {
            print("onChanged Start");
            Provider.of<Data>(context,listen:false).changeString(newText); //notice , listen default value is true
            print("onChanged End");
          },
        );
      }
    }
    
    

    context.read&lt;Data&gt;() 是对的,但你应该知道 context.read&lt;T&gt;() 等同于 Provider.of&lt;T&gt;(context,listen:false)

    正如documentation中提到的那样=>

    • context.watch&lt;T&gt;()Provider.of&lt;T&gt;(context)Provider.of&lt;T&gt;(context,listen:true) 相同,因为默认情况下 listen 为 true
    • context.read&lt;T&gt;() 等同于Provider.of&lt;T&gt;(context,listen:false)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-05-19
      • 2021-10-18
      • 2011-09-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-11
      相关资源
      最近更新 更多