如何在非父子组件之间共享数据

时间:2019-04-18 12:04:23

标签: angular

我想基于app.component中设置的变量禁用表单的提交按钮。组件没有父子关系。它们使用路线链接。 场景:我想根据选择的角色设置一个true或false值。因此,当选择角色时,将调用一个函数来设置布尔值。

我尝试使用共享服务,但无法检索其他组件中的变量值。我无法订阅布尔值。

app.component.html

<form #roleForm="ngForm">
    <select name="userRole" [(ngModel)]="viewSelected" (click)=SelectRole()>
      <option value="admin">Admin</option>
      <option value="layman">layman</option>
    </select>
  </form>

app.component.ts

SelectRole() {
    this._studentService.onSelectRole().subscribe(data);
  }

service.ts

public viewSelected = "admin";
public buttonDisabled : boolean = true;

onSelectRole() {
    if (this.viewSelected == "admin") {
      this.buttonDisabled = true;
    } else {
      this.buttonDisabled = false;
    }
  }

form.component.html =>这是我尝试使用布尔变量的地方


<form [formGroup]="addForm">

  <mat-label>First Name : </mat-label>
  <mat-form-field>
    <input matInput formControlName="firstName">
  </mat-form-field>
  <br><br>
  <button [disabled]="buttonDisabled" type="submit" (click)="onSubmit()">Submit</button>
</form>

我将角色保留在应用程序组件中,以便可以从任何组件中选择/更改角色。选择/更改角色后,我想根据角色禁用某些按钮。 那么我该如何实现呢?我在正确的轨道上吗?还是有其他方法可以做到这一点?

2 个答案:

答案 0 :(得分:0)

使用角度属性disabledreadonly(对于angular5 +)。例子:

<button [disable]=="viewSelected !== 'admin' " ...>
<button [readonly]="viewSelected !== 'admin' " ...>

如果您遇到角色正在更改但未在按钮中更新的问题,则需要ChangeDetectorRef。这是将其注入构造函数并检测更改的方式(类似于AngularJS中的$ scope。$ apply):

// Inject in your constructor:
constructor(private ref: ChangeDetectorRef) {
 ....
}


// And call this:
this.ref.detectChanges();

答案 1 :(得分:0)

这是一个经典的案例,您可以使用一个主题。

app.component.ts

this.roleChangeSubject$.next(role)

sibling.component.ts

roleSub$:Subscription<string>;
constructor(private sharedService:SharedService) {
this.roleSub$ = this.sharedService.roleChangeSubject$;
}

sibling.component.html

<button [disabled]="roleSub$ | async !== 'admin'"></button>

在服务中更新变量中的值不会在组件中更改,除非该变量是可观察的或侦听发生的值更改的主题。

在并非所有情况下都必须在极端情况下使用changeDetectorRef。