微服务、异步调用、在同级组件之间传输数据:将它们放在一起

Microservices, Async Calls, Transferring Data between Sibling Components: Putting it all together

我正在 Angular 制作工人打卡打卡申请,我需要建议。

该应用程序被组织为组件(sidenav.component.ts;home.component.ts;calendar.component.ts;workday.component.ts)和服务(home.service.ts;calendar.service.ts ).它有一个包含一个月中所有日期的日历。日历是一个数组,其中每个单位都是一天,有入口(AM 和 PM)和出口(am PM)以及工作人员可以添加的注释。这一切都受到 spring 安全保护。

我为此苦苦挣扎,因为很多时候我需要在组件和服务之间甚至组件之间(有时使用服务)交换数据。

这里有一个例子:

说我登录后我需要访问日历,但只有在它填充了来自用户的数据之后:用数据加载日历大约需要 10 秒,在那个时候我想要 sidenav 菜单停用!在我看来,这可以通过将服务 ("homeservice.lock") 中的布尔值从 false 更改为 true 来完成,以便在组件之间共享锁。但是当我尝试它时,即使锁定为真,菜单仍保持锁定状态。

这是上门服务


lock: Boolean = false

这是日历组件中的日历填充位

 this.calendarService.getDays(parameter).subscribe((res => {
    this.calendarCopy = JSON.parse(JSON.stringify(res));

    this.calendar= res;
      this.calendarService.saveCal(this.calendarCopy);
      if (this.calendarCopy){
        this.homeService.lock = true;
          console.log("the calendar is populated! The lock is true: " + this.homeService.lock)
      }
     

最后,这是导航组件。如您所见,只有在服务中的锁定为真时才能激活它。


export class MainNavComponent implements OnInit {
ngOnInit() {
   //link to the calendar
    this.setButton();
}

...
setButton(){
if (this.homeservice.lock){
 document.getElementByID("navbutton").removeAttribute("disabled")
}
...


但是侧边栏菜单没有解锁。我怀疑这是因为在 onInit 中并且在应用程序启动时布尔值仍然为假。在填充日历且布尔值为真后,菜单保持锁定状态。我需要一些以异步方式不断检查布尔值状态的东西!或者我需要一个不同的策略。

我一遍又一遍地遇到这个问题。我需要在组件之间共享数据,但我觉得这几乎是不可能的!我不能使用@Input 或@Output,因为它们不是嵌套组件,而是彼此完全独立且仅共享服务的兄弟组件。有时我可能需要将日期从日历组件发送到单个日期组件,用户可以在其中输入打卡和打卡数据,添加有关日期的注释等,因此每个“天”都有一个包含“ day.date、day.entranceAM、day.exitAM、day.entrancePM day.exitPM 和 day.notes".

这些组件有一个 templateUrl 而不仅仅是一个模板,所以我真的不能放一个小模板来填充我需要的东西。

问题是如何将它们组合在一起?我意识到我在谈论异步查询,因为我试图让两个独立的组件在不重新加载页面的情况下进行通信。我知道为此需要微服务,但我不能完全将它们放在一起!

协助会很有帮助!

如果您要在您的服务中使用可观察对象,这将是非常微不足道的。

查看您的服务可以公开 2 个可观察对象,days$isLocked$ 可观察对象。

export class CalendarService {
  
  public days$ = this.getDays().pipe(share());
  public isLocked$ = merge(
    of(true),
    this.days$.pipe(map(x => false))
  );

  private getDays() {
    return timer(2000)
      .pipe(
        map(x => [1,2,3,4,5,6,7])
      );
  }
}

isLocked$ observable 将发出初始值 true,当 getDays()(您的 API 调用)完成时,isLocked$ 将发出false.

那么你组件上的代码就比较简单了。

在 component.ts 文件中,您必须:

constructor(private calendarService: CalendarService) {}

public isLocked$ = this.calendarService.isLocked$;

在您的 component.html 文件上,只需执行

<button [disabled]="isLocked$ | async">I'm locked until the calendar is loaded</button>

编辑:

这里有一个 stackblitz link 来演示它:https://stackblitz.com/edit/angular-ivy-tdhcrf