#flutter #dart #provider
Вопрос:
У меня есть страница TemplateView, на которой есть параметр содержимого, на котором размещается содержимое, изменяющееся в зависимости от моего приложения. У каждого контента есть определенный поставщик. С другой стороны, на моей странице TemplateView есть кнопка, которая вызывает функцию проверки, общую для каждого поставщика.
Вот пример моего приложения (зеленым цветом показан мой шаблон, красным-содержимое, которое меняется):
Вот упрощенный код представления шаблона. Мы видим вызов содержимого и кнопку проверки, которая вызывает поставщика содержимого ContentView1.
class TemplateView extends StatelessWidget{ final String title; final StatelessWidget content; TemplateView ({ Key? key, required this.title, required this.content, required this.validationMessage, }) : super(key: key); @override Widget build(BuildContext context) { return GestureDetector( onTap: (() =gt; FocusScope.of(context).requestFocus(FocusNode())), child: SafeArea( child: Scaffold( appBar: AppBar( title: Text(title), ), body : _buildBody(context), ), ), ); } Widget _buildBody(BuildContext context) { // Here the call of my provider for the ContentView1 var _messageProvider = Provider.oflt;ContentView1Providergt;(context); return Column( children: [ SingleChildScrollView( child: Container( child: content, ), ), InkWell( child: Container( child: Text('SAVE'), ), onTap: () =gt; _messageProvider.validation() ), ], ); } }
И вот, как я называю TemplateView в своем маршрутизаторе:
case RouterName.kContentView1: return CupertinoPageRoute( builder: (context) =gt; ChangeNotifierProviderlt;ContentView1Providergt;( create: (BuildContext context) =gt; ContentView1Provider(), child: TemplateView( title: "Content 1 page", message: ContentView1(), ), ) );
All are working, now like I said the contents will change but my TemplateView is common. I therefore cannot enter in the TemplateView the call to the provider directly since it will change depending on the pages.
So I want to make the call to the provider in the TemplateView settings but it doesn’t work.
My new TemplateView:
class TemplateView extends StatelessWidget{ final String title; final StatelessWidget content; final Function validationMessage; // =gt; I added this line TemplateView({ Key? key, required this.title, required this.content, required this.validationMessage, // =gt; I added this line }) : super(key: key); @override Widget build(BuildContext context) { // =gt; I remove the call of the provider line return GestureDetector( onTap: (() =gt; FocusScope.of(context).requestFocus(FocusNode())), child: SafeArea( child: Scaffold( appBar: AppBar( title: Text(title), ), body : _buildBody(context), ), ), ); } Widget _buildBody(BuildContext context) { return Column( children: [ SingleChildScrollView( child: Container( child: content, ), ), InkWell( child: Container( child: Text('SAVE'), ), onTap: () =gt; validationMessage() // =gt; I changed this line ), ], ); } }
My new router :
case RouterName.kContentView1: return CupertinoPageRoute( builder: (context) =gt; ChangeNotifierProviderlt;ContentView1Providergt;( create: (BuildContext context) =gt; ContentView1Provider(), child: TemplateView( title: "Content 1 page", message: Content1View(), validationMessage: () =gt; Provider.oflt;ContentView1Providergt;(context).validation(), ), ) );
Это не работает, как это сделать ?
ОТРЕДАКТИРУЙТЕ с помощью решения, которое я добавил в свой маршрутизатор :
case RouterName.kContentView1: return CupertinoPageRoute( builder: (context) =gt; ChangeNotifierProviderlt;ContentView1Providergt;( create: (BuildContext context) =gt; ContentView1Provider(), child: TemplateView( title: "Content 1 page", message: Consumerlt;ContentView1Providergt;(builder :(ctx , provider , child){ return ContentView1(); }), validationMessage: () =gt; Provider.oflt;ContentView1Providergt;(context).validation(), ), ) );
Ответ №1:
Я не уверен, хорошо ли я понимаю этот случай, но я просто сообщаю идею, работает ли это, и понял ли я, о чем вы спрашиваете : в вашем поставщике пропусков маршрута на страницу Тамплейта :
case RouterName.kContentView1: return CupertinoPageRoute( builder: (context) =gt; ChangeNotifierProviderlt;ContentView1Providergt;( create: (BuildContext context) =gt; ContentView1Provider(), child: TemplateView( provider : ContentView1Provider , // add this line title: "Content 1 page", message: Content1View(), validationMessage: () =gt; Provider.oflt;ContentView1Providergt;(context).saveMessage(), ), ) );
в представлении шаблона получите этого поставщика :
class TemplateView extends StatelessWidget{ final provider; // add this line final String title; final StatelessWidget content; final Function validationMessage; // =gt; I added this line TemplateView({ Key? key, required this.provider, // add this line required this.title, required this.content, required this.validationMessage, // =gt; I added this line }) : super(key: key);
теперь вы можете использовать потребителя с поставщиком, которого вы получили для каждого контента :
return Consumerlt;providergt;(builder :(ctx , provider , child){ return //what you want ....; })
Может быть, я неправильно понял
Комментарии:
1. Это работа, спасибо за потраченное время ! Я редактирую свой пост.