angular2 订阅 return 值
angular2 subscribe return value
我在 validateUsernameIsUnique
方法中订阅了一个 http 请求服务。我正在尝试根据订阅中的代码操纵 validateUsernameIsUnique()
的 return 值。我确实阅读了一些关于异步行为的初学者文章。因此我知道下面的代码不起作用,因为 return ret;
未定义。不幸的是,我无法弄清楚如何实现我想要做的事情。
@Injectable()
export class ValidateService {
constructor(private _authService: AuthService) { }
...
validateUsernameIsUnique = (c: FormControl) => {
let ret;
if (c.value.length >= 3) {
this._authService.uniqueUser({ username: c.value }).subscribe(data => {
if (!data.success) { // Username already exists
ret = { usernameIsTaken: true };
}
else
ret = null;
})
return ret;
}
}
}
我订阅的授权服务如下所示:
import { Injectable } from '@angular/core';
import { Http, Headers } from '@angular/http';
import 'rxjs/add/operator/map';
@Injectable()
export class AuthService {
authToken: any;
user: any;
constructor(private _http: Http) { }
uniqueUser(user) {
let headers = new Headers();
headers.append('Content-Type', 'application/json');
return this._http.post('http://localhost:3000/users/username', user, { headers: headers })
.map(res => res.json());
}
}
更新 1:
将评论中提到的代码更改为
validateUsernameIsUnique = (c: FormControl) => {
if (c.value.length >= 3) {
return this._authService.uniqueUser({ username: 'zomh' }).map(res =>
{
if (!res.success) { // Username already exists
return { usernameIsTaken: true };
}
else
{
return null;
}
});
}
}
通话看起来像
ngOnInit() {
this.frmRegisterUser = new FormGroup({
name: new FormControl('',[Validators.required]),
username: new FormControl('',[Validators.required, this._validateService.validateUsernameIsUnique, Validators.minLength(3), this._validateService.validateUsernamePattern]),
email: new FormControl('',[Validators.required, this._validateService.validateEmailPattern]),
password: new FormControl('',[Validators.required, Validators.minLength(6)]),
acceptTerms: new FormControl(false,[Validators.required])
});
现在我正在接收一个看起来像这样的对象:
抱歉,我还是不明白在哪里可以找到映射的 returning 值,例如{ usernameIsTaken: true }
更新2
@pixelbits
它没有立即工作:我不知道如何正确调试它?,因为 console.logs 不会因为内部函数中的异步原因而被打印出来。我尝试输入一个已经在数据库中的用户名 'zomh'(不是唯一的)。
uniqueName(): AsyncValidatorFn {
console.log('i am here');
return (control:AbstractControl): Promise<ValidationResult> => {
let q = new Promise<ValidationResult>(
(resolve, reject)=> {
var name = 'zomh';
if (name == '') {
resolve(null);
}
else {
this._authService.uniqueUser({ username: 'zomh' })
.map(t=>t.json())
.subscribe(response=> {
if (response.success === false) {
resolve(response);
}
else
resolve(null);
});
}
});
return q;
}
}
我在控制台中收到了 "i am here"
,但仅此而已。我得到 null returned,即使它不应该使用现有的用户名。我可以验证 AuthService 是否正常工作(使用基本订阅和用户名测试它 'zomh')。
看来您需要将异步验证器实现为工厂:
import { AbstractControl, AsyncValidatorFn } from '@angular/forms';
import { Http } from '@angular/http';
import { Injectable, Inject } from '@angular/core';
import 'rxjs/add/operator/map';
interface ValidationResult {
[key:string]:boolean;
}
@Injectable()
export class ValidationService {
constructor(private _authService: AuthService) {
}
validateUsernameIsUnique(): AsyncValidatorFn {
return (control:AbstractControl): Promise<ValidationResult> => {
let q = new Promise<ValidationResult>(
(resolve, reject)=> {
var name = control.value;
if (name == '') {
resolve(null);
}
else {
this._authService.uniqueUser({ username: control.value })
//.map(t=>t.json()) // Auth Service already returning json
.subscribe(response=> {
if (response.success === false)
resolve({ usernameIsTaken: true });
else
resolve(null);
});
}
});
return q;
}
}
}
确保将验证器作为第三个参数传递(这是异步验证器所在的位置,第二个参数用于同步验证器)
this.formGroup = this.fb.group( {
'username': ['hello',, this.validationService.validateUsernameIsUnique()]
});
我在 validateUsernameIsUnique
方法中订阅了一个 http 请求服务。我正在尝试根据订阅中的代码操纵 validateUsernameIsUnique()
的 return 值。我确实阅读了一些关于异步行为的初学者文章。因此我知道下面的代码不起作用,因为 return ret;
未定义。不幸的是,我无法弄清楚如何实现我想要做的事情。
@Injectable()
export class ValidateService {
constructor(private _authService: AuthService) { }
...
validateUsernameIsUnique = (c: FormControl) => {
let ret;
if (c.value.length >= 3) {
this._authService.uniqueUser({ username: c.value }).subscribe(data => {
if (!data.success) { // Username already exists
ret = { usernameIsTaken: true };
}
else
ret = null;
})
return ret;
}
}
}
我订阅的授权服务如下所示:
import { Injectable } from '@angular/core';
import { Http, Headers } from '@angular/http';
import 'rxjs/add/operator/map';
@Injectable()
export class AuthService {
authToken: any;
user: any;
constructor(private _http: Http) { }
uniqueUser(user) {
let headers = new Headers();
headers.append('Content-Type', 'application/json');
return this._http.post('http://localhost:3000/users/username', user, { headers: headers })
.map(res => res.json());
}
}
更新 1:
将评论中提到的代码更改为
validateUsernameIsUnique = (c: FormControl) => {
if (c.value.length >= 3) {
return this._authService.uniqueUser({ username: 'zomh' }).map(res =>
{
if (!res.success) { // Username already exists
return { usernameIsTaken: true };
}
else
{
return null;
}
});
}
}
通话看起来像
ngOnInit() {
this.frmRegisterUser = new FormGroup({
name: new FormControl('',[Validators.required]),
username: new FormControl('',[Validators.required, this._validateService.validateUsernameIsUnique, Validators.minLength(3), this._validateService.validateUsernamePattern]),
email: new FormControl('',[Validators.required, this._validateService.validateEmailPattern]),
password: new FormControl('',[Validators.required, Validators.minLength(6)]),
acceptTerms: new FormControl(false,[Validators.required])
});
现在我正在接收一个看起来像这样的对象:
抱歉,我还是不明白在哪里可以找到映射的 returning 值,例如{ usernameIsTaken: true }
更新2 @pixelbits
它没有立即工作:我不知道如何正确调试它?,因为 console.logs 不会因为内部函数中的异步原因而被打印出来。我尝试输入一个已经在数据库中的用户名 'zomh'(不是唯一的)。
uniqueName(): AsyncValidatorFn {
console.log('i am here');
return (control:AbstractControl): Promise<ValidationResult> => {
let q = new Promise<ValidationResult>(
(resolve, reject)=> {
var name = 'zomh';
if (name == '') {
resolve(null);
}
else {
this._authService.uniqueUser({ username: 'zomh' })
.map(t=>t.json())
.subscribe(response=> {
if (response.success === false) {
resolve(response);
}
else
resolve(null);
});
}
});
return q;
}
}
我在控制台中收到了 "i am here"
,但仅此而已。我得到 null returned,即使它不应该使用现有的用户名。我可以验证 AuthService 是否正常工作(使用基本订阅和用户名测试它 'zomh')。
看来您需要将异步验证器实现为工厂:
import { AbstractControl, AsyncValidatorFn } from '@angular/forms';
import { Http } from '@angular/http';
import { Injectable, Inject } from '@angular/core';
import 'rxjs/add/operator/map';
interface ValidationResult {
[key:string]:boolean;
}
@Injectable()
export class ValidationService {
constructor(private _authService: AuthService) {
}
validateUsernameIsUnique(): AsyncValidatorFn {
return (control:AbstractControl): Promise<ValidationResult> => {
let q = new Promise<ValidationResult>(
(resolve, reject)=> {
var name = control.value;
if (name == '') {
resolve(null);
}
else {
this._authService.uniqueUser({ username: control.value })
//.map(t=>t.json()) // Auth Service already returning json
.subscribe(response=> {
if (response.success === false)
resolve({ usernameIsTaken: true });
else
resolve(null);
});
}
});
return q;
}
}
}
确保将验证器作为第三个参数传递(这是异步验证器所在的位置,第二个参数用于同步验证器)
this.formGroup = this.fb.group( {
'username': ['hello',, this.validationService.validateUsernameIsUnique()]
});