行为主题自动加载没有点击问题
Behavior Subject auto load without click issue
我一开始遇到了一个奇怪的问题我尝试提交表单它成功了没有任何问题这里是页面下面的代码摘录。
userRole.ts:
ngOnInit() {
const userSubscription = this.userManagementService.currentUsersIdValue.pipe(
switchMap((userId: string) => {
if (userId.length > 0) {
return this.userManagementService.getUsers(userId.toString());
}
else {
return this.userDetailsArr;
}
}
)).subscribe((users) => {
if (users !== null) {
const sbCreate = this.userManagementService.getUsersRole(users[0].id)
.subscribe((roles: any) => {
if (roles.length > 0) {
this.userRoleList = roles;
this.ref.detectChanges();
}
});
this.subscriptions.push(sbCreate);
}
});
this.subscriptions.push(userSubscription);
}
//// This is the process to submit form data
onSubmitRole() {
if (this.userRole.commonForm.invalid) {
alert('Please fill the form');
return;
}
const roleData = this.userRole.commonForm.value;
////This runs first time when I route to this page after re-routing to this page it starts again without clicking button
const userSubscribe = this.userManagementService.currentUsersIdValue.pipe(
switchMap((userId: string) => {
if (userId.length > 0) {
return this.userManagementService.getUsers(userId.toString());
}
else {
return this.userDetailsArr;
}
}
)).subscribe((users) => {
if (users !== null) {
this.authService.currentUserValue.forEach(u => {
if (roleData.RoleID) {
roleData.CompanyID = roleData.CompanyID;
roleData.CreatedBy = roleData.CreatedBy;
roleData.CreatedDate = roleData.CreatedDate;
roleData.LastModifiedDate = new Date().toLocaleString();
roleData.DefaultRoleID = '00000000-0000-0000-0000-000000000000';
}
else {
roleData.RoleID = '00000000-0000-0000-0000-000000000000';
roleData.CompanyID = u.companyID;
roleData.CreatedBy = u.id;
roleData.CreatedDate = new Date().toLocaleString();
roleData.LastModifiedBy = u.id;
roleData.LastModifiedDate = new Date().toLocaleString();
roleData.Internal = true;
roleData.RoleTypeCode = 1;
roleData.DefaultRoleID = '00000000-0000-0000-0000-000000000000';
}
const sbCreate = this.userManagementService.upsertUserRole(roleData)
.subscribe((response: any) => {
if (response.Status === 200) {
this.router.navigate(['general-management/viewprofile']);
}
else {
alert(response.Description);
}
});
this.subscriptions.push(sbCreate);
});
}
else {
if (confirm('Please edit/add any user to continue with Role!')) {
this.router.navigate(['general-management/viewprofile']);
}
}
});
this.subscriptions.push(userSubscribe);
}
现在的问题是,在页面 userRole.ts 的开头,当我点击提交以调用此方法时 onSubmitRole() 它将数据传递给服务,然后传递给服务器,成功后就可以了 当我编辑某个列表时,它会路由回 mainUser.ts 页面
从主页面到达userRole.ts页面然后出现奇怪的现象,它从onSubmitRole()
开始这个const userSubscribe = this.userManagementService.currentUsersIdValue.pipe
这个BehaviourSubject最初会第一次启动但是第二次编辑回到此页面后,它将自动再次启动 const userSubscribe = this.userManagementService.currentUsersIdValue.pipe
而不会点击 onSubmitRole().
过程如下 - mainUser.ts(有可以编辑路由到下一页的列表)--> userRole.ts(它有一个表单提交按钮,这里发生了奇怪的问题)它会自动在编辑时第二次运行服务。
这是userRole.Html页面
<div *ngIf="!showRolesTable">
<form [formGroup]="userRole.commonForm" (ngSubmit)="onSubmitRole()">
<div class="form-group">
<label for="RoleName">Role Name</label>
<input type="hidden" [(ngModel)]="userRole.RoleID" formControlName="RoleID">
<input type="text" [(ngModel)]="userRole.RoleName" formControlName="RoleName" id="RoleName" placeholder="Enter Role Name">
</div>
<div class="form-group">
<label for="Description">Description</label>
<input type="text" [(ngModel)]="userRole.Description" formControlName="Description" class="form-control"
id="Description" placeholder="Enter Description">
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
JS 中没有魔法 - 如果没有人在调用 onSubmitRole()
(你放入调试器语句但它没有触发),那么这意味着之前的订阅仍然有效。
当您执行 const userSubscribe = this.userManagementService.currentUsersIdValue.pipe(...).subscribe(...)
时,您正在创建一个订阅,它将持续监听 currentUsersIdValue
中的变化。唯一的可能性是,当您第二次转到 userRole
页面时,该可观察对象会发出一些东西并导致 userRole
的 previous 实例触发管道触发的任何内容.
至于解决方案... 1) 确保在用户离开 userRole
页面时清除订阅,这实际上可能是泄漏。 2) 在管道的最开头添加一个 take(1)
运算符:一旦收到 1 个值,此运算符将自动取消订阅。
请务必unsubscribe
从您的订阅。在您的组件中实现 OnDestroy()
接口,然后调用 subscription.unsubscribe()
。此外,如果您不需要 Observable
中的先前值,那么最好使用 Subject()
而不是 BehaviourSubject()
。 Read more on the different types of Subjects in RxJs
我一开始遇到了一个奇怪的问题我尝试提交表单它成功了没有任何问题这里是页面下面的代码摘录。
userRole.ts:
ngOnInit() {
const userSubscription = this.userManagementService.currentUsersIdValue.pipe(
switchMap((userId: string) => {
if (userId.length > 0) {
return this.userManagementService.getUsers(userId.toString());
}
else {
return this.userDetailsArr;
}
}
)).subscribe((users) => {
if (users !== null) {
const sbCreate = this.userManagementService.getUsersRole(users[0].id)
.subscribe((roles: any) => {
if (roles.length > 0) {
this.userRoleList = roles;
this.ref.detectChanges();
}
});
this.subscriptions.push(sbCreate);
}
});
this.subscriptions.push(userSubscription);
}
//// This is the process to submit form data
onSubmitRole() {
if (this.userRole.commonForm.invalid) {
alert('Please fill the form');
return;
}
const roleData = this.userRole.commonForm.value;
////This runs first time when I route to this page after re-routing to this page it starts again without clicking button
const userSubscribe = this.userManagementService.currentUsersIdValue.pipe(
switchMap((userId: string) => {
if (userId.length > 0) {
return this.userManagementService.getUsers(userId.toString());
}
else {
return this.userDetailsArr;
}
}
)).subscribe((users) => {
if (users !== null) {
this.authService.currentUserValue.forEach(u => {
if (roleData.RoleID) {
roleData.CompanyID = roleData.CompanyID;
roleData.CreatedBy = roleData.CreatedBy;
roleData.CreatedDate = roleData.CreatedDate;
roleData.LastModifiedDate = new Date().toLocaleString();
roleData.DefaultRoleID = '00000000-0000-0000-0000-000000000000';
}
else {
roleData.RoleID = '00000000-0000-0000-0000-000000000000';
roleData.CompanyID = u.companyID;
roleData.CreatedBy = u.id;
roleData.CreatedDate = new Date().toLocaleString();
roleData.LastModifiedBy = u.id;
roleData.LastModifiedDate = new Date().toLocaleString();
roleData.Internal = true;
roleData.RoleTypeCode = 1;
roleData.DefaultRoleID = '00000000-0000-0000-0000-000000000000';
}
const sbCreate = this.userManagementService.upsertUserRole(roleData)
.subscribe((response: any) => {
if (response.Status === 200) {
this.router.navigate(['general-management/viewprofile']);
}
else {
alert(response.Description);
}
});
this.subscriptions.push(sbCreate);
});
}
else {
if (confirm('Please edit/add any user to continue with Role!')) {
this.router.navigate(['general-management/viewprofile']);
}
}
});
this.subscriptions.push(userSubscribe);
}
现在的问题是,在页面 userRole.ts 的开头,当我点击提交以调用此方法时 onSubmitRole() 它将数据传递给服务,然后传递给服务器,成功后就可以了 当我编辑某个列表时,它会路由回 mainUser.ts 页面
从主页面到达userRole.ts页面然后出现奇怪的现象,它从onSubmitRole()
开始这个const userSubscribe = this.userManagementService.currentUsersIdValue.pipe
这个BehaviourSubject最初会第一次启动但是第二次编辑回到此页面后,它将自动再次启动 const userSubscribe = this.userManagementService.currentUsersIdValue.pipe
而不会点击 onSubmitRole().
过程如下 - mainUser.ts(有可以编辑路由到下一页的列表)--> userRole.ts(它有一个表单提交按钮,这里发生了奇怪的问题)它会自动在编辑时第二次运行服务。
这是userRole.Html页面
<div *ngIf="!showRolesTable">
<form [formGroup]="userRole.commonForm" (ngSubmit)="onSubmitRole()">
<div class="form-group">
<label for="RoleName">Role Name</label>
<input type="hidden" [(ngModel)]="userRole.RoleID" formControlName="RoleID">
<input type="text" [(ngModel)]="userRole.RoleName" formControlName="RoleName" id="RoleName" placeholder="Enter Role Name">
</div>
<div class="form-group">
<label for="Description">Description</label>
<input type="text" [(ngModel)]="userRole.Description" formControlName="Description" class="form-control"
id="Description" placeholder="Enter Description">
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
JS 中没有魔法 - 如果没有人在调用 onSubmitRole()
(你放入调试器语句但它没有触发),那么这意味着之前的订阅仍然有效。
当您执行 const userSubscribe = this.userManagementService.currentUsersIdValue.pipe(...).subscribe(...)
时,您正在创建一个订阅,它将持续监听 currentUsersIdValue
中的变化。唯一的可能性是,当您第二次转到 userRole
页面时,该可观察对象会发出一些东西并导致 userRole
的 previous 实例触发管道触发的任何内容.
至于解决方案... 1) 确保在用户离开 userRole
页面时清除订阅,这实际上可能是泄漏。 2) 在管道的最开头添加一个 take(1)
运算符:一旦收到 1 个值,此运算符将自动取消订阅。
请务必unsubscribe
从您的订阅。在您的组件中实现 OnDestroy()
接口,然后调用 subscription.unsubscribe()
。此外,如果您不需要 Observable
中的先前值,那么最好使用 Subject()
而不是 BehaviourSubject()
。 Read more on the different types of Subjects in RxJs