繁体   English   中英

使用EventEmitter时,为什么我的Angular页面没有刷新?

[英]Why doesn't my Angular page refresh when using an EventEmitter?

当我的EventEmitter发出事件时,我的角度SPA不会刷新。

这是子组件中的EventEmitter

import { Component, OnInit, Output, EventEmitter } from '@angular/core';
import { Todo } from '../todo';

@Component({
  selector: 'app-add-todo',
  templateUrl: './add-todo.component.html',
  styleUrls: ['./add-todo.component.css']
})
export class AddTodoComponent implements OnInit {
  newTodo: Todo = new Todo();

  @Output() addTodoEvent: EventEmitter<Todo> = new EventEmitter();

  constructor() { }

  addTodo() {
    this.addTodoEvent.emit(this.newTodo);
    console.log('event emitted');
    this.newTodo = new Todo();
    console.log('new todo created');
  }

  ngOnInit() {
  }

}

这是使用它的模板:

<div class="container">
  <app-add-todo (addTodoEvent)='onAddTodo($event)'></app-add-todo>
   // other template stuff
</div>

这是onAddTodo的声明:

  onAddTodo(todo: Todo) {
    console.log('onAddTodo called');
    this.todoDataService.addTodo(todo);
  }

基本上,该应用程序可以工作,但是在进行任何更改后,我必须按F5刷新页面。

要注意的一件事是,当我使用数组作为数据源时,此方法可以正常工作,但是当我转到json-server和Observables时,页面停止刷新。

我很高兴提供任何可能需要的进一步信息。

更新:

这是addTodo

  addTodo(todo: Todo): void {
    this.aHttpService.post<Todo>(`http://localhost:3000/todos`, todo).subscribe(
      val => {
        console.log('POST call successful value returned in body', val);
      },
      response => {
        console.log('POST call in error', response);
      },
      () => {
        console.log('The POST observable is now completed.');
      }
    );
  }

列出待办事项的完整代码如下:

import { Component, OnInit } from '@angular/core';
import { Todo } from '../todo';
import { TodoDataService } from '../todo-data.service';
import { Observable } from 'rxjs/Observable';

@Component({
  selector: 'app-todo-list',
  templateUrl: './todo-list.component.html',
  styleUrls: ['./todo-list.component.css']
})
export class TodoListComponent implements OnInit {
  constructor(private todoDataService: TodoDataService) {}

  completetodos: Observable<Array<Todo>>;
  incompletetodos: Observable<Array<Todo>>;

  onAddTodo(todo: Todo) {
    console.log('onAddTodo called');
    this.todoDataService.addTodo(todo);
  }

  toggleTodoComplete(todo) {
    this.todoDataService.toggleTodoComplete(todo);
  }

  removeTodo(todo) {
    this.todoDataService.deleteTodoById(todo.id);
  }

  editTodo(todo: Todo) {
    todo.editMode = true;
  }

  updateTodo(todo: Todo, editInput) {
    todo.title = editInput.value;
    todo.editMode = false;
    this.todoDataService.updateTodoById(todo.id, todo);
  }

  allTasks(): Observable<Array<Todo>> {
    return this.todoDataService.getAllTodos();
  }

  completedTodos(): Observable<Array<Todo>> {
    return this.todoDataService.completedTodos();
  }

  incompletedToDos(): Observable<Array<Todo>> {
    return this.todoDataService.incompletedTodos();
  }

  ngOnInit() {
    this.completetodos = this.completedTodos();
    this.incompletetodos = this.incompletedToDos();
  }
}

您的服务应返回如下所示的可观察对象:

 addTodo(todo: Todo): void {
    return this.aHttpService.post<Todo>(`http://localhost:3000/todos`, todo);
 }

并在这样的组件中使用它:

 onAddTodo(todo: Todo) {
    this.todoDataService.addTodo(todo).subscribe(val => {
       this.incompletetodos.push(val);
    });;
 }

(我最小化了代码)


参考: https : //angular.io/tutorial/toh-pt6#add-a-new-hero

src / app / heroes / heroes.component.ts(添加)

add(name: string): void {
  name = name.trim();
  if (!name) { return; }
  this.heroService.addHero({ name } as Hero)
    .subscribe(hero => {
      this.heroes.push(hero);
    });
}

src / app / hero.service.ts(addHero)

/** POST: add a new hero to the server */
addHero (hero: Hero): Observable<Hero> {
  return this.http.post<Hero>(this.heroesUrl, hero, httpOptions).pipe(
    tap((hero: Hero) => this.log(`added hero w/ id=${hero.id}`)),
    catchError(this.handleError<Hero>('addHero'))
  );
}

使用EventEmitter时,为什么我的Angular页面没有刷新?

您可能会这样想,我们正在使用Angular构建一个不会导致刷新整个页面的单页应用程序,我们只是更新了网站的一部分。

基本上,该应用程序可以工作,但是在进行任何更改后,我必须按F5刷新页面。

因为每当您按F5键时,都会很好地重新初始化Angular应用程序,从而触发此生命周期挂钩:

ngOnInit() {
    this.completetodos = this.completedTodos();
    this.incompletetodos = this.incompletedToDos();
}

因此,您的应用程序反映了数据库的最新数据。

有一点要注意的是,这个曾经我使用数组作为数据源时的工作,但我去的时候JSON服务器和观测量, 页面停止刷新

实际上,当您使用数组作为数据源时,我们的应用程序根本不会刷新。 这就是所谓的数据绑定 ,我们在UI上看到的数据被绑定到Angular应用程序保存的数据(在客户端,在客户端的内存中)。

与服务器通信时,当我们在服务器的数据库中进行某些更改时,我们必须根据服务器的响应来更新客户端的数据。 在这种情况下,这就是我们在您的Todo App中要做的事情。

成功保存待办事项后,您必须更新可观察对象

 onAddTodo(todo: Todo) {
this.todoDataService.addTodo(todo).subscribe(
      val => {
         // here you have to update the observables //incompletetodos.next(newTodo)
      },
      response => {
        console.log('POST call in error', response);
      },
      () => {
        console.log('The POST observable is now completed.');
      }
    );
}

您也不需要在这里订阅

 addTodo(todo: Todo): void {
    return this.aHttpService.post<Todo>(`http://localhost:3000/todos`, todo);
  }

我认为push不适用于observable,您可以参考下面的链接将一个新项附加到incompletetodos observable数组中

如何将项目附加到Observable

如果您要使用BehaviorSubject(另一种类型的observable)代替Observable,则可以轻松添加一个新项目。 像下面这样

incompletetodos: BehaviorSubject<Array<Todo>> = BehaviorSubject.empty<Array<Todo>>();

//您可以像下面这样推送一个新项目

 incompletetodos.next(newTodo)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM