由ProxyProvider进行的Flutter注入返回null

时间:2019-09-28 12:12:19

标签: flutter

GITHUB SAMPLE PROJECT

这是我的简单类,我想用ProxyProvider注入WebParserApi并得到空值,

class RetrievePageSummarizedInformation extends StatesRebuilder {
  BuiltUserProfile builtUserProfile = BuiltUserProfile();
  final WebParserApi _api;

  RetrievePageSummarizedInformation({WebParserApi api}) : _api = api;

  retrievePageProfileInfo(BuildContext context,String username) async {
    //_preparePageProfileCache();
    //WebParserApi _api = Provider.of<WebParserApi>(context);
    return await _api.getProfileRetrieveFromParser(username);
  }

  void _preparePageProfileCache() async {
    await KvStore().createTable('userProfile');
  }
}

主要功能:

void main() async {
  Provider.debugCheckInvalidValueType = null;

  _setUpLogging();

  runApp(MultiProvider(providers: providers, child: OKToast(child: StartupApplication())));
}

proxyProvider实现:

List<SingleChildCloneableWidget> providers = [
    ...independentServices, 
    ...dependentServices, 
    ...uiConsumableProviders
];

List<SingleChildCloneableWidget> independentServices = [
  Provider(
    builder: (_) => WebParserApi.create(),
    dispose: (_, WebParserApi service) => service.client.dispose(),
  )
];

List<SingleChildCloneableWidget> dependentServices = [
  ProxyProvider<WebParserApi, RetrievePageSummarizedInformation>(
    builder: (context, api, retrievePageSummarizedInformation) => RetrievePageSummarizedInformation(api: api),
  )
];

List<SingleChildCloneableWidget> uiConsumableProviders = [

];

这是我的WebParserApi类的实现:

@ChopperApi(baseUrl: '/')
abstract class WebParserApi extends ChopperService {
  @Get(path: '{token}')
  Future<Response<BuiltUserProfile>> getProfileRetrieveFromParser(@Path() String username);

  static WebParserApi create() {
    final client = ChopperClient(
        client: http.IOClient(
          HttpClient()..connectionTimeout = const Duration(seconds: 60),
        ),
        baseUrl: 'https://www.sample.com',
        services: [
          _$WebParserApi(),
        ],
        converter: BuiltValueConverter(),
        interceptors: [
          HeadersInterceptor({'Content-Type': 'application/json'}),
          HttpLoggingInterceptor(),
        ]);
    return _$WebParserApi(client);
  }
}

问题在这里。将WebParserApi注入RetrievePageSummarizedInformation类:

return Injector<RetrievePageSummarizedInformation>(
  models: [() => RetrievePageSummarizedInformation()],
  builder: (context, model) => Stack(
    children: <Widget>[
      ),
    ],
  ),
);

我在链接https://github.com/MahdiPishguy/proxy_provider_sample上的github上创建了一个简单项目,因为当我尝试使用_pageInformation.pageProfile('test');时,PageInformation类的_api变量为null。在主要班级

3 个答案:

答案 0 :(得分:1)

我的问题解决了,我们必须在用Provider.of(context)定义的类上使用ProxyProvider

class RetrievePageSummarizedInformation extends StatesRebuilder {
  BuiltUserProfile builtUserProfile = BuiltUserProfile();
  final WebParserApi _api;

  RetrievePageSummarizedInformation({@required WebParserApi api}) : _api = api;

  getPageProfileInfo(String username) async {
    final res = await _api.getSimpleProfileInformation(username);
    return res;
  }
}

注射液:

models: [() => RetrievePageSummarizedInformation(api:Provider.of(context))],

答案 1 :(得分:0)

您遇到PageInformation _pageInformation = PageInformation();的问题。您可能最好从public class MyDateTimePicker : DateTimePicker { /// <summary> /// Occurs when the property Value is changed programmatically. /// </summary> public event EventHandler<EventArgs> ValueChangedProgrammatically; /// <summary> /// Gets or sets a boolean that indicates if the calendar popup is open. /// </summary> public bool IsOpen { get; private set; } /// <summary> /// Raises the ValueChangedProgrammatically event. /// </summary> /// <param name="e">Event arguments.</param> protected virtual void OnValueChangedProgrammatically(EventArgs e) { ValueChangedProgrammatically?.Invoke(this, e); } /// <summary> /// Raises the DropDown event. /// </summary> /// <param name="e">Event arguments.</param> protected override void OnDropDown(EventArgs e) { base.OnDropDown(e); IsOpen = true; } protected override void OnCloseUp(EventArgs e) { base.OnCloseUp(e); IsOpen = false; } /// <summary> /// Raises the ValueChanged event. /// </summary> /// <param name="e">Event arguments.</param> protected override void OnValueChanged(EventArgs e) { base.OnValueChanged(e); if (!Focused && !IsOpen) { /* If the control has no focus and the calendar is not opened, the value is most likely changed programmatically. */ OnValueChangedProgrammatically(e); } } } 获取_pageInformation,而不是手动创建contextapi的新空实例。这将起作用:

null

https://pub.dev/packages/provider#reading-a-value

  

读取值的最简单方法是使用静态方法 ... @override Widget build(BuildContext context) { // here Provider.of<PageInformation>(context).pageProfile('test'); return Scaffold( appBar: AppBar( title: Text(widget.title), ), body: Center( ... 。该方法将从与传递的BuildContext关联的小部件开始的小部件树中查找,并将返回找到的Provider.of<T>(BuildContext context)类型的最近变量(如果找不到则抛出)。

希望这会有所帮助。

答案 2 :(得分:-3)

ProxyProvider更改为ChangeNotifierProxyProvider

 MultiProvider(
      providers: [
        ChangeNotifierProxyProvider<WebParserApi, RetrievePageSummarizedInformation>(
          builder: (_, api, __) => RetrievePageSummarizedInformation(api: api),
        ),
      ],
 )