微服务、异步调用、在同级组件之间传输数据:将它们放在一起
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
我正在 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