如何将 Stream<String> 值作为参数传递给在 bloc 文件 FLUTTER 中创建的函数

How to pass Stream<String> values as parameters to a function created in a bloc file FLUTTER

我有一个登录 bloc 文件,我在其中创建了 2 个流用户名和密码

class LoginBloc {
  LoginRepository _loginRepository = new LoginRepository();
  StreamController _loginController = StreamController<Response<LoginModel>>();

  //declare streams
  final _userName = BehaviorSubject<String>();
  final _password = BehaviorSubject<String>();

  //get data from streams
  StreamSink<Response<LoginModel>> get loginControllerSink =>
  _loginController.sink;
  Stream<String> get loginUserName => _userName.stream;
  Stream<String> get loginPassword => _password.stream;
  Stream<bool> get submitLoginForm =>
      Rx.combineLatest2(loginUserName, loginPassword, (a, b) => true);

  Function(String) get changeLoginUserName => _userName.sink.add;
  Function(String) get changeLoginPassword => _password.sink.add;

  //dispose
  dispose() {
    _userName.close();
    _password.close();
  }

  //functions
  login(email, password, context) async {
    try {
      LoginModel data = await _loginRepository.loginIntoSystem(email, password);
      loginControllerSink.add(Response.completed(data));    
      Navigator.pushNamed(context, '/dashboard');
    } catch (e) {
      loginControllerSink.add(Response.error(e.toString()));
      print(e);
    }
  }
}

这是login.dart

    class Login extends StatefulWidget {
  @override
  _LoginState createState() => _LoginState();
}

class _LoginState extends State<Login> {
  bool _passwordVisible = false;
  @override
  Widget build(BuildContext context) {
    Size size = MediaQuery.of(context).size;
    final LoginBloc bloc = LoginProvider.of(context);
    return Scaffold(
      backgroundColor: Colors.white,
      body: SingleChildScrollView(
        child: SafeArea(
          child: Center(
            child:
            Column(
              children: <Widget>[
                SizedBox(height: size.height*0.05),
                Icon(
                  Icons.track_changes,
                  size: size.width*0.06,
                ),
                SizedBox(height: size.height*0.02),
                Text('Login',
                    style: TextStyle(
                        color: Color(0xff005D6C),
                        fontSize: size.width*0.02,
                        fontWeight: FontWeight.bold,
                        fontStyle: FontStyle.italic)),
                SizedBox(height: size.height*0.04),
                Container(
                  width: size.width * 0.2,
                  padding: EdgeInsets.only(bottom: 20.0),
                  child: StreamBuilder<String>(
                      stream: bloc.loginUserName,
                      builder: (context, snapshot) {
                        return TextField(
                          onChanged: bloc.changeLoginUserName,
                          decoration: new InputDecoration(
                              contentPadding: EdgeInsets.symmetric(vertical: 0, horizontal: 15.0),
                              border: new OutlineInputBorder(
                                  borderSide: const BorderSide(
                                      width: 2.0, style: BorderStyle.solid),
                                  borderRadius: BorderRadius.circular(50.0)),
                              focusedBorder: OutlineInputBorder(
                                borderSide: const BorderSide(
                                    color: Colors.grey, width: 2.0),
                                borderRadius: BorderRadius.circular(50.0),
                              ),
                              hintText: 'User Name',
                              hintStyle: new TextStyle(
                                  color: Colors.grey,
                                  fontWeight: FontWeight.bold),
                              suffixIcon: const Icon(
                                Icons.person,
                                size: 30.0,
                                color: Colors.grey,
                              ),
                              errorText: snapshot.error),
                        );
                      }),
                ),
                Container(
                  width: size.width * 0.2,
                  padding: EdgeInsets.only(bottom: 20.0),
                  child: StreamBuilder<String>(
                      stream: bloc.loginPassword,
                      builder: (context, snapshot) {
                        return TextField(
                          onChanged: bloc.changeLoginPassword,
                          obscureText: !_passwordVisible,
                          maxLength: 20,
                          decoration: new InputDecoration(
                              contentPadding: EdgeInsets.symmetric(vertical: 0, horizontal: 15.0),
                              border: new OutlineInputBorder(
                                  borderSide: const BorderSide(
                                      width: 2.0, style: BorderStyle.solid),
                                  borderRadius: BorderRadius.circular(50.0)),
                              focusedBorder: OutlineInputBorder(
                                borderSide: const BorderSide(
                                    color: Colors.grey, width: 2.0),
                                borderRadius: BorderRadius.circular(50.0),
                              ),
                              hintText: 'Password',
                              hintStyle: new TextStyle(
                                  color: Colors.grey,
                                  fontWeight: FontWeight.bold),
                              prefixIcon: const Icon(
                                Icons.lock,
                                size: 30.0,
                                color: Colors.grey,
                              ),
                              suffixIcon: IconButton(
                                icon: Icon(
                                  // Based on passwordVisible state choose the icon
                                  _passwordVisible
                                      ? Icons.visibility
                                      : Icons.visibility_off,
                                  color: Colors.grey,
                                ),
                                onPressed: () {
                                  setState(() {
                                    _passwordVisible = !_passwordVisible;
                                  });
                                },
                              ),
                              errorText: snapshot.error),
                        );
                      }),
                ),

                Container(
                  width: size.width * 0.2,
                  child: ClipRRect(
                    borderRadius: BorderRadius.circular(29),
                    child: StreamBuilder<bool>(
                      stream: bloc.submitLoginForm,
                      builder: (context, snapshot){
                        return FlatButton(
                          color: Color(0XFFEFEFEF),
                          textColor: primaryColor,
                          disabledColor: Colors.grey,
                          disabledTextColor: Colors.black,
                          padding: EdgeInsets.symmetric(
                              vertical: 12.0, horizontal: 10.0),
                          onPressed: () => snapshot.hasError ? null : bloc.login(bloc.loginUserName, bloc.loginPassword, context) ,
                          child: Text(
                            "Login",
                            style: TextStyle(
                                fontSize: 20.0,
                                fontWeight: FontWeight.bold,
                                fontStyle: FontStyle.italic),
                          ),
                        );
                      },
                    ),
                  ),
                )
              ],
            )
          ),
        ),
      ),
    );
  }
}

我在单击登录按钮时调用登录函数,并将用户名、密码和上下文作为参数传递。但是点击它给出 "预期类型 'String' 的值,但得到类型 'BehaviorSubject'" 中的一个值

添加了 loginIntoSystem:

Future<LoginModel> loginIntoSystem(String email, String password) 
async {
    dynamic body = {
      'email': email,
      'password': password
    };
    final response = await _provider.post("/login", body);
    return LoginModel.fromJson(response);
  }

有没有办法将 BehaviorSubject 转换为 String ?

你是对的。我错了,行为主体有一个 属性 value 那个行为主体的 returns 值。您可以使用它从您的行为主体中获取电子邮件和密码。此外,由于您的 bloc 文件已经可以访问这些变量,因此您不必将它们作为 onPressed 函数的参数传递。

login(context) async {
    final email = _userName.value;
    final password = _password.value;
    try {
      LoginModel data = await _loginRepository.loginIntoSystem(email, password);
      loginControllerSink.add(Response.completed(data));    
      Navigator.pushNamed(context, '/dashboard');
    } catch (e) {
      loginControllerSink.add(Response.error(e.toString()));
      print(e);
    }
  }

我找到了解决方案。

通过使用值 属性,我能够获取这些值。

    final fEmail = _email.value;
    final fPassword =  _password.value;

感谢大家花时间发布答案。