在 ngrx 成功操作后如何清理我的表单?
How can I clean my form after a ngrx succeeded action?
我有反应形式:
const createFormGroup = (dataItem?: Usuario) => {
if (dataItem) {
return new FormGroup({
id: new FormControl(dataItem.id),
nome: new FormControl(dataItem.nome),
cidade: new FormControl(dataItem.cidade)
});
}
return new FormGroup({
id: new FormControl(),
nome: new FormControl(''),
cidade: new FormControl('')
});
};
这是我的模板:
<form (ngSubmit)="save()" [formGroup]="formGroup">
<input formControlName="nome" type="text" class="form-control" id="inputName" placeholder="Nome">
<input formControlName="cidade" type="text" class="form-control" id="exampleInputPassword1"
<button id="my-element" type="submit" class="btn btn-primary">Complete
</button>
</form>
单击 "submit" 后,我使用 ngrx 效果进行了一次保存数据的调度:
save() {
const user = this.formGroup.value;
if (user.id === null) {
this.store.dispatch(createUser({ user: user }));
} else {
this.store.dispatch(updateUser({ user: user }));
}
}
这是我的效果:
public saveUser$ = createEffect(() =>
this.actions$.pipe(
ofType(createUser),
switchMap((action) =>
this.usuarioService.save(action.user).pipe(
map(() => loadUsers()),
catchError((error) => of(loadUsers()))
)
)
)
);
有人可以告诉我是否有一种方法可以在我的效果没有进入 catchError 时清除我的反应?
使用This.formGroup.reset()根据要清除表单值的条件重置表单
- 如果您想以 ngrx 方式执行此操作,请根据您的效果调用另一个操作以确保成功。
saveUser$ = createEffect(() =>
this.actions$.pipe(
ofType(createUser),
switchMap((action) =>
this.usuarioService.save(action.user).pipe(
map(() => {
loadUsers();
return new clearFormAction();
}),
catchError((error) => of(loadUsers()))
)
)
)
);
- 在
clearFormAction()
. 的 reducer 中将表单数据重置为空(一般情况下为初始状态)
case clearFormAction: {
return {
...state,
id: '',
nome: '',
cidade: ''
};
}
- 在您的组件 ngOnInit() 中订阅商店表单数据
this.storeFormData$ = this.store.select(formData);
this.storeFormData.subscribe(formData => {
this.formGroup.setValue(formData);
});
- 因此,只要您的
this.usuarioService.save()
成功,您的表格就会被清除。
如果您只想在确定操作已成功分派后清除表单,我会设置一个简单的服务,其中包含一个可观察对象,当 this.usuarioService.save
成功时,该对象会由您的效果更新:
效果:
您需要将 Subject
导入您的效果文件:
import { Subject } from 'rxjs';
然后添加如下服务。这可以在一个单独的文件中,但为了简单起见,将它添加到效果文件的顶部,紧挨着所有 "imports"
@Injectable({
providedIn: 'root'
})
export class ClearFormService {
private clearFormSource = new Subject<boolean>();
clearForm$ = this.clearFormSource.asObservable();
clearForm() {
this.clearFormSource.next(true);
}
}
接下来,将此服务添加到您的效果中的构造函数中 class:
constructor(private clearFormService: ClearFormService) { }
如果您的构造函数中已经有引用,请添加:
private clearFormService: ClearFormService
...到最后。
您可以在 this.usuarioService.save
成功后更新此服务中的可观察对象。注意大括号已添加到 map
。有 'more rxjs' 种方法,但我认为这很好:
public saveUser$ = createEffect(() =>
this.actions$.pipe(
ofType(createUser),
switchMap((action) =>
this.usuarioService.save(action.user).pipe(
map(() => {
this.clearFormService.clearForm(); // Updates your service
return loadUsers();
}),
catchError((error) => of(loadUsers()))
)
)
)
);
具有表单的组件:
然后在带有表单的组件中,您需要从效果文件中导入 ClearFormService
并将其添加到构造函数中,与在效果文件中所做的相同。您可能还需要导入 subscription
:
import { Subscription } from 'rxjs';
然后您可以订阅 clearForm$
,并在收到回复时清除表单。
clearFormSubscription = new Subscription();
ngOnInit() {
this.clearFormSubscription = this.clearFormService.clearForm$.subscribe(response => {
this.formGroup.reset()
console.log('Clear Form Here');
})
}
不要忘记取消订阅 onDestroy!
ngOnDestroy() {
this.clearFormSubscription.unsubscribe()
}
您可以设置一个使用您的 ngrx 商店的解决方案,但我认为这会过度设计。
也许只是观察组件中的状态,如果特定 属性 指示操作已成功执行,则进行所有重置。
ngOnInit(): void {
this.watchOperations();
// ...
}
watchOperations(): void {
this.store
.pipe(
select(state => state.todos.succeeded)
)
.subscribe(succeeded => {
if (succeeded) {
this.store.dispatch(LOAD());
this.formSubmitted = false;
this.form.reset(this.formDefaults);
}
});
}
说到效果:
createEffect(() => this.actions$.pipe(
ofType(ADD),
mergeMap(({ payload }) => {
return this.todosService.add(payload)
.pipe(
map(() => ({ type: '[Todos] Add Success' })),
catchError(() => of({ type: '[Todos] Add Fail' }))
);
})
));
组件:
addTodo(): void {
this.formSubmitted = true;
if (this.form.valid) {
this.store.dispatch(ADD({
payload: {
...this.form.value,
done: false
} as ITodo
}));
}
}
和减速器:
// ...
on(ADD, (state, action) => {
return {
...state,
processed: action.payload,
processing: true
};
}),
on(ADD_SUCCESS, (state) => {
return {
...state,
processing: false,
succeeded: true
};
}),
on(ADD_FAIL, (state) => {
return {
...state,
processing: false,
succeeded: false
};
}),
// ...
我有反应形式:
const createFormGroup = (dataItem?: Usuario) => {
if (dataItem) {
return new FormGroup({
id: new FormControl(dataItem.id),
nome: new FormControl(dataItem.nome),
cidade: new FormControl(dataItem.cidade)
});
}
return new FormGroup({
id: new FormControl(),
nome: new FormControl(''),
cidade: new FormControl('')
});
};
这是我的模板:
<form (ngSubmit)="save()" [formGroup]="formGroup">
<input formControlName="nome" type="text" class="form-control" id="inputName" placeholder="Nome">
<input formControlName="cidade" type="text" class="form-control" id="exampleInputPassword1"
<button id="my-element" type="submit" class="btn btn-primary">Complete
</button>
</form>
单击 "submit" 后,我使用 ngrx 效果进行了一次保存数据的调度:
save() {
const user = this.formGroup.value;
if (user.id === null) {
this.store.dispatch(createUser({ user: user }));
} else {
this.store.dispatch(updateUser({ user: user }));
}
}
这是我的效果:
public saveUser$ = createEffect(() =>
this.actions$.pipe(
ofType(createUser),
switchMap((action) =>
this.usuarioService.save(action.user).pipe(
map(() => loadUsers()),
catchError((error) => of(loadUsers()))
)
)
)
);
有人可以告诉我是否有一种方法可以在我的效果没有进入 catchError 时清除我的反应?
使用This.formGroup.reset()根据要清除表单值的条件重置表单
- 如果您想以 ngrx 方式执行此操作,请根据您的效果调用另一个操作以确保成功。
saveUser$ = createEffect(() =>
this.actions$.pipe(
ofType(createUser),
switchMap((action) =>
this.usuarioService.save(action.user).pipe(
map(() => {
loadUsers();
return new clearFormAction();
}),
catchError((error) => of(loadUsers()))
)
)
)
);
- 在
clearFormAction()
. 的 reducer 中将表单数据重置为空(一般情况下为初始状态)
case clearFormAction: {
return {
...state,
id: '',
nome: '',
cidade: ''
};
}
- 在您的组件 ngOnInit() 中订阅商店表单数据
this.storeFormData$ = this.store.select(formData);
this.storeFormData.subscribe(formData => {
this.formGroup.setValue(formData);
});
- 因此,只要您的
this.usuarioService.save()
成功,您的表格就会被清除。
如果您只想在确定操作已成功分派后清除表单,我会设置一个简单的服务,其中包含一个可观察对象,当 this.usuarioService.save
成功时,该对象会由您的效果更新:
效果:
您需要将 Subject
导入您的效果文件:
import { Subject } from 'rxjs';
然后添加如下服务。这可以在一个单独的文件中,但为了简单起见,将它添加到效果文件的顶部,紧挨着所有 "imports"
@Injectable({
providedIn: 'root'
})
export class ClearFormService {
private clearFormSource = new Subject<boolean>();
clearForm$ = this.clearFormSource.asObservable();
clearForm() {
this.clearFormSource.next(true);
}
}
接下来,将此服务添加到您的效果中的构造函数中 class:
constructor(private clearFormService: ClearFormService) { }
如果您的构造函数中已经有引用,请添加:
private clearFormService: ClearFormService
...到最后。
您可以在 this.usuarioService.save
成功后更新此服务中的可观察对象。注意大括号已添加到 map
。有 'more rxjs' 种方法,但我认为这很好:
public saveUser$ = createEffect(() =>
this.actions$.pipe(
ofType(createUser),
switchMap((action) =>
this.usuarioService.save(action.user).pipe(
map(() => {
this.clearFormService.clearForm(); // Updates your service
return loadUsers();
}),
catchError((error) => of(loadUsers()))
)
)
)
);
具有表单的组件:
然后在带有表单的组件中,您需要从效果文件中导入 ClearFormService
并将其添加到构造函数中,与在效果文件中所做的相同。您可能还需要导入 subscription
:
import { Subscription } from 'rxjs';
然后您可以订阅 clearForm$
,并在收到回复时清除表单。
clearFormSubscription = new Subscription();
ngOnInit() {
this.clearFormSubscription = this.clearFormService.clearForm$.subscribe(response => {
this.formGroup.reset()
console.log('Clear Form Here');
})
}
不要忘记取消订阅 onDestroy!
ngOnDestroy() {
this.clearFormSubscription.unsubscribe()
}
您可以设置一个使用您的 ngrx 商店的解决方案,但我认为这会过度设计。
也许只是观察组件中的状态,如果特定 属性 指示操作已成功执行,则进行所有重置。
ngOnInit(): void {
this.watchOperations();
// ...
}
watchOperations(): void {
this.store
.pipe(
select(state => state.todos.succeeded)
)
.subscribe(succeeded => {
if (succeeded) {
this.store.dispatch(LOAD());
this.formSubmitted = false;
this.form.reset(this.formDefaults);
}
});
}
说到效果:
createEffect(() => this.actions$.pipe(
ofType(ADD),
mergeMap(({ payload }) => {
return this.todosService.add(payload)
.pipe(
map(() => ({ type: '[Todos] Add Success' })),
catchError(() => of({ type: '[Todos] Add Fail' }))
);
})
));
组件:
addTodo(): void {
this.formSubmitted = true;
if (this.form.valid) {
this.store.dispatch(ADD({
payload: {
...this.form.value,
done: false
} as ITodo
}));
}
}
和减速器:
// ...
on(ADD, (state, action) => {
return {
...state,
processed: action.payload,
processing: true
};
}),
on(ADD_SUCCESS, (state) => {
return {
...state,
processing: false,
succeeded: true
};
}),
on(ADD_FAIL, (state) => {
return {
...state,
processing: false,
succeeded: false
};
}),
// ...