如何检测从一个组件到另一个组件的变化

时间:2017-12-20 19:31:26

标签: angular typescript angular2-changedetection

Angular 4. Github source

我有一个由Web服务填充的菜单。 Web服务位于taskService中,但现在不是必需的。

ngOnInit() {
    this.getTasks();
    }
    getTasks(): void {
        this.taskService.getTasks()
            .subscribe(Tasks => this.tasks = Tasks);
    } 

当您单击某个任务时,它会加载一个页面,一个不同的组件,并且表单已准备好更新数据。它也是由Web服务制作的,工作正常。 问题是更新任务后,它没有反映在任务菜单中

我正在导入此内容:

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。

2 个答案:

答案 0 :(得分:3)

我看了你的代码。问题是import keras from keras.layers.merge import Maximum, Minimum from IPython.display import SVG from keras.utils.vis_utils import model_to_dot n_timesteps_in = 20 n_features=2 input_tensor = keras.layers.Input(shape = [n_timesteps_in, n_features]) out = keras.layers.LSTM(150)(input_tensor) out = keras.layers.RepeatVector(n_timesteps_in)(out) out = keras.layers.LSTM(150, return_sequences=True)(out) out = keras.layers.TimeDistributed(keras.layers.Dense(n_features))(out) out = Minimum()([out, input_tensor]) model = keras.Model(input_tensor, out ) SVG(model_to_dot(model, show_shapes=True, show_layer_names=True, rankdir='HB').create(prog='dot', format='svg')) 更新了您的任务,但view-task.component未收到有关此交易的通知。我认为navigation.component可能只适合你。

您可以阅读更多相关信息here

我假设您在整个应用程序中都有BehaviorSubject的单个数组,您可以在tasks组件上显示它们。

Task.service.ts

navigation

Navigation.component.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    
              });
     }
}

查看-task.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);
      }
 }

我自己没有尝试过这段代码。但是,我之前已在我的应用程序中实现了类似的功能。所以当你尝试并遇到问题时,请告诉我。

答案 1 :(得分:2)

Angular没有运行sudo supervisorctl start horizon ,因为你没有要求它。您changeDetection方法中的ViewTaskComponent中的实例变量都没有更新。

在代码中,save完成后,它会返回updateTask()中的save()。但是在ViewTaskComponent的订阅回调中没有指向this.task的链接。

由于this.taskService.updateTask()使用了PATCH请求,我假设你没有得到整个updateTask对象。所以你不能只说Task

相反,您可以在该订阅回调中调用this.task = valuePassedToSubscribeCallback并获取整个更新的this.viewTask()对象。

例如:

Task

注意:我的第二个@Bunyamin Coskuner建议使用this.taskService.updateTask(task, id) .subscribe( // new line here to fetch the updated Task object this.viewTask() ); (甚至标准BehaviorSubject)。如果你想要一个重构器,那么它们就是一种在你的服务中管理状态的简洁方法。