Tôi đang tạo biểu mẫu đăng nhập đơn giản (email và mật khẩu) để thử và tăng cường kỹ năng lập trình phản ứng của mình. Tôi đang gặp một số vấn đề khi xác thực trường email hoạt động theo cách tôi muốn.Sử dụng RxJava để xác thực đăng nhập email, có thể quan sát được hai lần
Dưới đây là mã của tôi:
final Observable<CharSequence> email = RxTextView.textChanges(emailView);
Observable<Boolean> emailIsValid = email.map(new Func1<CharSequence, Boolean>() {
@Override
public Boolean call(CharSequence charSequence) {
Log.d("asdf", "emailIsValid call: " + charSequence);
return Pattern.matches(Patterns.EMAIL_ADDRESS.pattern(), charSequence);
}
});
RxView.focusChanges(emailView)
.withLatestFrom(emailIsValid, new Func2<Boolean, Boolean, Boolean>() {
@Override
public Boolean call(Boolean hasFocus, Boolean emailIsValid) {
return (!hasFocus && !emailIsValid);
}
})
.subscribe(new Action1<Boolean>() {
@Override
public void call(Boolean showError) {
if (showError) {
emailInputLayout.setError("Enter a valid email");
} else {
emailInputLayout.setError(null);
}
}
});
Observable<CharSequence> password = RxTextView.textChanges(passwordView);
Observable.combineLatest(emailIsValid, password,
new Func2<Boolean, CharSequence, Boolean>() {
@Override
public Boolean call(Boolean emailIsValid, CharSequence password) {
Log.d("asdf", "valid: " + emailIsValid + ", password: " + password);
return (emailIsValid && password.length() > 0);
}
})
.subscribe(RxView.enabled(loginButton));
Và đây là nhật ký:
emailIsValid call: emailIsValid call: valid: false, password: // I type 'j' emailIsValid call: j emailIsValid call: j valid: false, password: // I type 'a' emailIsValid call: ja emailIsValid call: ja valid: false, password:
Như bạn thấy, emailIsValid
được gọi là hai lần mỗi khi tôi gõ một ký tự, có nghĩa là nó đang làm một regex phù hợp hai lần, đó là loại lãng phí.
Tôi tra cứu cách tôi có thể thực hiện emailIsValid
chỉ gọi một lần cho mỗi thay đổi, bất kể số người đăng ký có và tôi đã tìm thấy phương thức share()
. Đây là những gì sẽ xảy ra khi tôi thêm .share()
đến hết khai emailIsValid
's:
emailIsValid call: // I type 'j' emailIsValid call: j valid: false, password: // I type 'a' emailIsValid call: ja valid: false, password:
Đó giải quyết vấn đề, nhưng nó gây ra khác: Không có Emit ban đầu bởi emailIsValid
đến combineLatest
chức năng ở cuối, do đó, nút Đăng nhập bắt đầu được bật, khi nút này sẽ bị tắt (chuyển sang màu xám).
Cách sạch nhất để giải quyết vấn đề này là gì? Tôi nghĩ rằng Tôi muốn nó hoạt động như một số BehaviorSubject
, nhưng tôi không chắc đó có phải là cách tốt nhất để làm điều đó hay không.
Tuyệt vời, không nhận thức được các quan sát có thể kết nối. Hoạt động tốt, cảm ơn bạn! –
@ D_Steve595 NP. Vui vì tôi có thể giúp! – pt2121