В вашем первом примере NewWidget
создается с новым BuildContext
, у которого уже есть доступ к его предку, поэтому этот виджет может видеть созданного вами поставщика с помощью: context.read<Model>()
.
Но во втором примере вы создаете и используете своего провайдера в одном и том же виджете Main
, поэтому все на одном BuildContext
, и когда вы запустите context.read<Model>()
, flutter попытается найти в вашем дереве виджетов. чтобы найти Model
, но он не найдет его, потому что вы только что его создали. Это сценарий, в котором вы могли бы использовать виджет Builder :
class Main extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (context) => Model(),
child: Scaffold(
appBar: AppBar(
title: Text('test'),
),
body: Builder(
// Here the magic happens
// this builder function will generate a new BuilContext for you
builder: (BuildContext newContext){
return RaisedButton(
child: Text(
"test",
),
onPressed: () {
newContext.read<Model>().save();
},
);
}
),
),
);
}
}
Используя виджет Builder
, вы можете создать новый BuildContext
контейнер. может использоваться для получения информации о только что созданном вами поставщике, потому что ваш виджет Builder создается после вашего ChangeNotifierProvider и является его дочерним элементом, поэтому он может легко искать и находить эту информацию на своем родительском элементе.
Также обратите внимание на то, что вам говорят ошибки, компилятор flutter действительно умен с такого рода проблемами:
Убедитесь, что Main находится под вашим MultiProvider / Provider. Обычно это происходит, когда вы создаете поставщика и пытаетесь прочитать его немедленно.
Эти строки точно говорят вам то, что я объяснял ранее.