流构建器中快照上的data = null

时间:2019-12-15 19:40:31

标签: flutter dart

我正在尝试第一次使用流将视图模型连接到屏幕,但是却难以完全理解该概念。

我的屏幕:

class LoginAndSignupScreen extends StatefulWidget {
  LoginAndSignupScreen({@required this.viewModel});

  final LoginAndSignupScreenViewModelType viewModel;

  @override
  State<StatefulWidget> createState() => new _LoginAndSignupScreenState();
}

class _LoginAndSignupScreenState extends State<LoginAndSignupScreen> {
  Widget showErrorMessage() {
    return StreamBuilder<String>(
      initialData: "",
      stream: widget.viewModel.errorText,
      builder: (context, snapshot) {
          return new Text(
            snapshot.data,
            style: TextStyle(
                fontSize: 13.0,
                color: Colors.red,
                height: 1.0,
                fontWeight: FontWeight.w300
            ),
          );
        }
    );
  }

我的视图模型:

abstract class LoginAndSignupScreenViewModelType {
  Stream<String> get errorText;

  void signIn(String email, String password);
  void signUp(String email, String password, String firstName, String lastName);
}

class LoginAndSignupScreenViewModel implements LoginAndSignupScreenViewModelType {
  LoginAndSignupScreenViewModel({@required this.authenticationService,
                                 @required this.cloudStoreService});

  final AuthenticationServiceType authenticationService;
  final CloudStoreServiceType cloudStoreService;

  final errorController = StreamController<String>.broadcast();

  @override
  Stream<String> get errorText => errorController.stream;

  @override
  void signIn(String email, String password) async {
    try {
      String userId = await authenticationService.signIn(email, password);
      User user = await cloudStoreService.fetchUserWithId(userId)
        .whenComplete(loginCallback);
      print('Signed in: ${user.firstName} ${user.lastName}');
    } catch (error) {
      errorController.add(error);
    }
  }

  @override 
  void signUp(String email, String password, String firstName, String lastName) async {
    try {
      String userId = await authenticationService.signUp(email, password);
      User user = new User(userId, firstName, lastName);
      await cloudStoreService.createUser(user)
        .then(showHomeScreenIfValidUser);
      print('Signed up user: ${user.id}');
    } catch (error) {
        errorController.add(error);
    }
  }
}

执行此操作并运行时,出现一条错误,提示我理解snapshot.data = null。我的问题是,如果没有错误字符串,我希望没有小部件。

有人可以帮忙吗?

1 个答案:

答案 0 :(得分:1)

要回答您的问题,可以根据snapshot.data的值返回不同的小部件:

stream: widget.viewModel.errorText,
builder: (context, snapshot) {
  if (snapshot.hasData) {
    return Text(
      snapshot.data,
      style: TextStyle(
          fontSize: 13.0,
          color: Colors.red,
          height: 1.0,
          fontWeight: FontWeight.w300
      ),
    );
  }

  // returns an invisible widget
  return SizedBox.shrink();

}

此外,您是否知道可以同时产生数据和错误的Stream?我想知道为什么您对所有内容都使用回调而不是仅使用一个流,其中snapshot.data有数据,而snapshot.error有错误。