简体   繁体   English

如何通过 Stream<string> 值作为在块文件 FLUTTER 中创建的 function 的参数</string>

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

I have a login bloc file where I have created 2 streams username and password我有一个登录块文件,其中创建了 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);
    }
  }
}

Here's the login.dart这是登录名。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),
                          ),
                        );
                      },
                    ),
                  ),
                )
              ],
            )
          ),
        ),
      ),
    );
  }
}

I am calling the login function on CLick of login button and passing the username, password and context as parameters.我在登录按钮的 CLick 上调用登录 function 并将用户名、密码和上下文作为参数传递。 But on click its giving "Expected a value of type 'String', but got one of type 'BehaviorSubject'"但是点击它给出“期望'String'类型的值,但得到'BehaviorSubject'类型之一”

added the loginIntoSystem:添加了 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);
  }

Is there a way to convert BehaviorSubject to String?有没有办法将 BehaviorSubject 转换为字符串?

I found the solution.我找到了解决方案。

By using value property, I was able to get the values.通过使用 value 属性,我能够获取值。

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

Thank you everyone for taking your time and posting the answers.感谢大家抽出宝贵的时间并发布答案。

You are right.你说的对。 I was wrong, and behavior subject has a property value which returns value of that behavior subject.我错了,行为主体有一个属性value ,它返回该行为主体的值。 You can use this to get the email and password out of your behavior subject.您可以使用它从您的行为主题中获取 email 和密码。 Also, since your bloc file already has access to those variables, you don't have to pass them as arguments from your onPressed function.此外,由于您的 bloc 文件已经可以访问这些变量,因此您不必将它们作为 arguments 从您的 onPressed function 传递。

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);
    }
  }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM