如何检测从一个组件到另一个组件的变化
How to detect change from one component into other
Angular 4. Github source
我有一个由 Web 服务填充的菜单。 Web 服务在 taskService 中,但现在不是必需的。
ngOnInit() {
this.getTasks();
}
getTasks(): void {
this.taskService.getTasks()
.subscribe(Tasks => this.tasks = Tasks);
}
当您单击一个任务时,它会加载一个页面,一个不同的组件,其中包含一个准备好更新数据的表单。它也是由网络服务制作的并且工作正常。 问题是更新任务后,在任务菜单中没有体现
我正在导入这个:
import { Component, OnInit, ChangeDetectorRef } from '@angular/core';
并将其添加到构造函数中:
private cdRef: ChangeDetectorRef
这是我使用 detectChanges() 函数的最佳方法,在使用 save() 函数更新数据后
this.taskService.updateTask(task, id)
.subscribe(
this.Ref.detach();
setInterval(() => {
this.Ref.detectChanges();
}, 5000);
);
这是菜单中的 html 打印任务:
<li *ngFor="let task of tasks" class="d-inline-block col-md-12">
<a routerLink="/task/{{task.id}}" > {{task.title}}</a>
<!-- <span class="close big"></span> -->
<button class="close big" title="delete task"
(click)="delete(task)">x</button>
</li>
这是更新任务的形式
<form (ngSubmit)="save(taskName.value, taskBody.value)" #taskForm="ngForm" class="example-form">
<mat-form-field class="example-full-width">
<label>Task Name</label>
<input matInput [(ngModel)]="task.name" #taskName name="name">
</mat-form-field>
<mat-form-field class="example-full-width">
<textarea matInput [(ngModel)]="task.body" #taskBody name="body"></textarea>
</mat-form-field>
<button type="submit" class="btn btn-success" >Save</button>
</form>
两者在不同的组件中。
我已尝试遵循此 tutorial,但我卡住了,我不知道如何使用 ChangeDetectorRef。
我看过你的代码。问题是 view-task.component
更新了您的任务,但是 navigation.component
没有收到有关此事务的通知。我认为 BehaviorSubject
可能正适合你。
您可以阅读更多相关信息here
我假设您在整个应用程序中只有一个 tasks
数组,并且您会在 navigation
组件上显示它们。
Task.service.ts
export class TaskService {
// behaviorSubject needs an initial value.
private tasks: BehaviorSubject = new BehaviorSubject([]);
private taskList: Task[];
getTasks() {
if (!this.taskList || this.taskList.length === 0) {
this.initializeTasks();
}
return this.tasks.asObservable();
}
initializeTasks() {
this.http.get('api/tasks')
.subscribe(tasks => {
// next method will notify all of the subscribers
this.tasks.next(tasks);
}, error => {
// proper error handling here
});
}
updateTasks(task: Task) {
this.http.post('api/updateTask')
.subscribe(resp => {
// update your tasks array
this.tasks = ...
// and call next method of your behaviorSubject with updated list
this.tasks.next(this.tasks);
}, error => {
// proper error handling here
});
}
}
Navigation.component.ts
export class NavigationComponent implements OnInit{
tasks: Task[];
constructor(private taskService: TaskService) {}
ngOnInit() {
// this method will be called every time behaviorSubject
// emits a next value.
this.taskService.getTasks()
.subscribe(tasks => this.tasks = tasks);
}
}
查看-task.component.ts
export class ViewTaskComponent {
constructor(private taskService: TaskService) {}
updateTask(task: Task) {
this.taskService.updateTask(task);
}
}
我自己还没有尝试过这段代码。但是,我以前在我的应用程序中实现过类似的东西。因此,当您尝试并遇到问题时,请告诉我。
Angular 不是 运行 changeDetection
因为你没有要求它。 ViewTaskComponent
中的 None 个实例变量正在您的 save
方法中更新。
在您的代码中,在 updateTask()
完成后,它会在您的 ViewTaskComponent
中 returns 到 save()
。但是this.taskService.updateTask()
的订阅回调中没有link到this.task
。
由于 updateTask
使用 PATCH 请求,我假设您没有取回整个 Task
对象。所以你不能只说 this.task = valuePassedToSubscribeCallback
.
相反,您可以在该订阅回调中调用 this.viewTask()
并获取整个更新的 Task
对象。
例如:
this.taskService.updateTask(task, id)
.subscribe(
// new line here to fetch the updated Task object
this.viewTask()
);
注意:我赞成@Bunyamin Coskuner 的建议,使用 BehaviorSubject
(甚至是标准的 Subject
)。如果您准备进行重构,它们是在您的服务中管理状态的一种干净方式。
Angular 4. Github source
我有一个由 Web 服务填充的菜单。 Web 服务在 taskService 中,但现在不是必需的。
ngOnInit() {
this.getTasks();
}
getTasks(): void {
this.taskService.getTasks()
.subscribe(Tasks => this.tasks = Tasks);
}
当您单击一个任务时,它会加载一个页面,一个不同的组件,其中包含一个准备好更新数据的表单。它也是由网络服务制作的并且工作正常。 问题是更新任务后,在任务菜单中没有体现
我正在导入这个:
import { Component, OnInit, ChangeDetectorRef } from '@angular/core';
并将其添加到构造函数中:
private cdRef: ChangeDetectorRef
这是我使用 detectChanges() 函数的最佳方法,在使用 save() 函数更新数据后
this.taskService.updateTask(task, id)
.subscribe(
this.Ref.detach();
setInterval(() => {
this.Ref.detectChanges();
}, 5000);
);
这是菜单中的 html 打印任务:
<li *ngFor="let task of tasks" class="d-inline-block col-md-12">
<a routerLink="/task/{{task.id}}" > {{task.title}}</a>
<!-- <span class="close big"></span> -->
<button class="close big" title="delete task"
(click)="delete(task)">x</button>
</li>
这是更新任务的形式
<form (ngSubmit)="save(taskName.value, taskBody.value)" #taskForm="ngForm" class="example-form">
<mat-form-field class="example-full-width">
<label>Task Name</label>
<input matInput [(ngModel)]="task.name" #taskName name="name">
</mat-form-field>
<mat-form-field class="example-full-width">
<textarea matInput [(ngModel)]="task.body" #taskBody name="body"></textarea>
</mat-form-field>
<button type="submit" class="btn btn-success" >Save</button>
</form>
两者在不同的组件中。
我已尝试遵循此 tutorial,但我卡住了,我不知道如何使用 ChangeDetectorRef。
我看过你的代码。问题是 view-task.component
更新了您的任务,但是 navigation.component
没有收到有关此事务的通知。我认为 BehaviorSubject
可能正适合你。
您可以阅读更多相关信息here
我假设您在整个应用程序中只有一个 tasks
数组,并且您会在 navigation
组件上显示它们。
Task.service.ts
export class TaskService {
// behaviorSubject needs an initial value.
private tasks: BehaviorSubject = new BehaviorSubject([]);
private taskList: Task[];
getTasks() {
if (!this.taskList || this.taskList.length === 0) {
this.initializeTasks();
}
return this.tasks.asObservable();
}
initializeTasks() {
this.http.get('api/tasks')
.subscribe(tasks => {
// next method will notify all of the subscribers
this.tasks.next(tasks);
}, error => {
// proper error handling here
});
}
updateTasks(task: Task) {
this.http.post('api/updateTask')
.subscribe(resp => {
// update your tasks array
this.tasks = ...
// and call next method of your behaviorSubject with updated list
this.tasks.next(this.tasks);
}, error => {
// proper error handling here
});
}
}
Navigation.component.ts
export class NavigationComponent implements OnInit{
tasks: Task[];
constructor(private taskService: TaskService) {}
ngOnInit() {
// this method will be called every time behaviorSubject
// emits a next value.
this.taskService.getTasks()
.subscribe(tasks => this.tasks = tasks);
}
}
查看-task.component.ts
export class ViewTaskComponent {
constructor(private taskService: TaskService) {}
updateTask(task: Task) {
this.taskService.updateTask(task);
}
}
我自己还没有尝试过这段代码。但是,我以前在我的应用程序中实现过类似的东西。因此,当您尝试并遇到问题时,请告诉我。
Angular 不是 运行 changeDetection
因为你没有要求它。 ViewTaskComponent
中的 None 个实例变量正在您的 save
方法中更新。
在您的代码中,在 updateTask()
完成后,它会在您的 ViewTaskComponent
中 returns 到 save()
。但是this.taskService.updateTask()
的订阅回调中没有link到this.task
。
由于 updateTask
使用 PATCH 请求,我假设您没有取回整个 Task
对象。所以你不能只说 this.task = valuePassedToSubscribeCallback
.
相反,您可以在该订阅回调中调用 this.viewTask()
并获取整个更新的 Task
对象。
例如:
this.taskService.updateTask(task, id)
.subscribe(
// new line here to fetch the updated Task object
this.viewTask()
);
注意:我赞成@Bunyamin Coskuner 的建议,使用 BehaviorSubject
(甚至是标准的 Subject
)。如果您准备进行重构,它们是在您的服务中管理状态的一种干净方式。