Flutter (web) 提供者不能在发布模式下工作,但在调试模式下工作。

问题描述 投票:0回答:1

我遇到了一些奇怪的行为,一个Provider在调试模式和发布模式下表现不同。

这个问题发布在关闭 这个问题.

下面是对功能的简单描述。我有一个 ExpansionTiles 列表(在其主体中包含 TextFormFields)和一个 FloatingActionButton,用于添加到 ExpansionTiles 列表中。在这两个部件下面我有一个Back按钮和一个Next按钮。只要ExpansionTiles列表中的任何TextFormField不完整,Next按钮就需要 "不可用"(即向用户抛出一个错误信息,颜色为灰色)。一旦所有的TextFormFields都准备好了,Next按钮应该改变颜色,并将用户引导到一个新的页面。改变颜色和功能在调试中可以正常工作,但在发布模式下就不行了(即运行:flutter build web后)。

首先:TravelProceedModel监控用户是否可以点击下一步按钮的状态。即:这只是一个简单的bool。每当updateCanProceed()被调用时,我都会更新canProceed,同时也会通知Listeners()。

import 'package:flutter/material.dart';

class TravelProceedModel extends ChangeNotifier {

  bool canProceed;

  void updateCanProceed(bool value) {

    canProceed = value;

    notifyListeners();
  }
}

其次,TravelProceedModel是使用ChangeNotifierProvider然后使用Consumer实现的。我期望(这在调试中是可行的),当canProceed被改变时,这一行。"nextEnabled: proceedModel.canProceed "应该会导致按钮变色。然而,这只在调试模式下有效。

class TravelDeductionTrips extends StatefulWidget {
  @override
  _TravelDeductionTripsState createState() => _TravelDeductionTripsState();
}

class _TravelDeductionTripsState extends State<TravelDeductionTrips> {

@override
Widget build(BuildContext context) {
  String year = Provider.of<UserSelectionsModel>.(context).selected_report["year"];
  String report = Provider.of<UserSelectionsModel>(context).selected_report["report"];

  return MultiProvider(
    providers: [
     ChangeNotifierProvider(
       create: (context) => TravelProceedModel()
     ),
     ChangeNotifierProvider(
       create: (context) => TravelModel(
         year: year,
         report: report,
       ),
     ),
    ],
    child: Consumer<TravelModel>(
      builder: (context, travelModel, child) {
       return FutureBuilder(
         future: travelModel.fetchTripsToLocalSession(),
         builder: (context, data) {
           if (data.connectionState == ConnectionState.done) {
             return Column(
               children: <Widget>[
                 TravelDeductionTripList(),
                 Consumer<TravelProceedModel>(
                   builder: (context, proceedModel, child) {
                     proceedModel.updateCanProceed(
                       travelModel.checkProceedCondition()
                     );
                     return BackNextButtons(
                       backEnabled: true,
                       nextEnabled: proceedModel.canProceed,
                       backText: "Tilbage",
                       nextText: travelModel.trips["next_action_title"],
                       errorMessage: travelModel.proceedErrorMessage,
                       nextFunction: () async {
                         await addQuestionIDtoStack(year, report, travelModel.trips["next_question_id"], true);
                       }, // No special function is needed, this is just a simple next
                     );
                   },
                 ),
               ],
             );
           } else {
             return Center(
               child: CircularProgressIndicator(),
             );
           }
         }
      );
    }
  ),
);
}
}

NB! proceedModel.canProceed是从TravelDeductionTripList()中更新的,它调用了

Provider.of<TravelProceedModel>(context, listen: false).updateCanProceed(
  Provider.of<TravelModel>(context, listen: false).checkProceedCondition()
);

下一步按钮只有在重新加载小组件后才会改变颜色,也就是说,看起来TravelProceedModel被更新了,但在UI中并没有被重新绘制--虽然在调试模式下是完美的。也就是说,看起来TravelProceedModel被更新了,但是widget并没有在UI中被重新绘制--尽管在调试模式下它完美地发生了。

有谁知道为什么调试能用而发布不能用?

下面是我的 "flutter doctor -v"。注意,这是一个flutter web项目。

[✓] Flutter (Channel beta, v1.15.17, on Mac OS X 10.15.2 19C57, locale en-US)
    • Flutter version 1.15.17 at /Users/danni/Documents/flutter/flutter
    • Framework revision 2294d75bfa (13 days ago), 2020-03-07 00:28:38 +0900
    • Engine revision 5aff311948
    • Dart version 2.8.0 (build 2.8.0-dev.12.0 9983424a3c)


[✓] Android toolchain - develop for Android devices (Android SDK version 29.0.2)
    • Android SDK at /Users/danni/Library/Android/sdk
    • Android NDK location not configured (optional; useful for native profiling support)
    • Platform android-29, build-tools 29.0.2
    • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 1.8.0_202-release-1483-b49-5587405)
    • All Android licenses accepted.

[✗] Xcode - develop for iOS and macOS
    ✗ Xcode installation is incomplete; a full installation is necessary for iOS development.
      Download at: https://developer.apple.com/xcode/download/
      Or install Xcode via the App Store.
      Once installed, run:
        sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer
        sudo xcodebuild -runFirstLaunch
    ✗ CocoaPods installed but not working.
        You appear to have CocoaPods installed but it is not working.
        This can happen if the version of Ruby that CocoaPods was installed with is different from the one being used
        to invoke it.
        This can usually be fixed by re-installing CocoaPods. For more info, see
        https://github.com/flutter/flutter/issues/14293.
      To re-install CocoaPods, run:
        sudo gem install cocoapods

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 3.5)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin version 41.0.2
    • Dart plugin version 191.8593
    • Java version OpenJDK Runtime Environment (build 1.8.0_202-release-1483-b49-5587405)

[✓] VS Code (version 1.43.0)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.8.1

[✓] Connected device (2 available)
    • Chrome     • chrome     • web-javascript • Google Chrome 80.0.3987.149
    • Web Server • web-server • web-javascript • Flutter Tools

! Doctor found issues in 1 category.
dart provider flutter-web
1个回答
0
投票

我也遇到了同样的问题,我已经为它做了一个变通方法。

listen 是一个参数,你可以将任何其他的bool变量传递给它(不应该是常量true或false)。

中有一个内置的 bool 变量 foundation.dart 包,称为 kReleaseMode.

所以这里有一个例子,我如何处理调试和发布模式之间的监听器问题。

await Provider.of<AuthService>(context, listen: kReleaseMode).loginUser(
                  user: _username, password: _password);

对我来说,它工作得很完美。

© www.soinside.com 2019 - 2024. All rights reserved.