为什么我的 Angular 页面在使用 EventEmitter 时不刷新?
Why doesn't my Angular page refresh when using an EventEmitter?
当我的 EventEmitter 发出事件时,我的 angular 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();
}
}
您的服务应该 return observable 是这样的:
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'))
);
}
Why doesn't my Angular page refresh when using an EventEmitter?
您可能会这样想,我们正在使用 Angular 构建不会导致任何整页刷新的单页应用程序,我们只更新网站的一部分。
Basically, the application works, but I have to hit F5 to refresh the
page after any change is made.
因为无论何时您按下 F5,您的 Angular 应用程序都会重新初始化,从而触发此生命周期挂钩:
ngOnInit() {
this.completetodos = this.completedTodos();
this.incompletetodos = this.incompletedToDos();
}
因此,您的应用程序反映了数据库的最新数据。
One thing to note is that this used to work when I was using an array
as a data source, but when I went to json-server and Observables, the
page stopped refreshing.
事实上,当您使用数组作为数据源时,我们的应用程序根本不会刷新。这就是所谓的 data-binding,我们在 UI 上看到的数据绑定到 Angular 应用程序持有的数据(在客户端,在客户的记忆)。
在与服务器通信时,当我们对服务器的数据库进行一些更改时,我们必须根据服务器的响应更新客户端的数据。这就是我们在这种情况下在您的待办事项应用程序中的做法。
一旦你完成了 todo 的成功保存,你必须更新 observables
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 对 observables 不起作用,你可以参考下面的 link 将一个新项目追加到 incompletetodos observable 数组中
如果您使用 BehaviorSubject(另一种类型的可观察对象)而不是 Observable,您可以轻松添加新项目。如下所示
incompletetodos: BehaviorSubject<Array<Todo>> = BehaviorSubject.empty<Array<Todo>>();
//你可以像下面这样推送一个新项目
incompletetodos.next(newTodo)
当我的 EventEmitter 发出事件时,我的 angular 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();
}
}
您的服务应该 return observable 是这样的:
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'))
);
}
Why doesn't my Angular page refresh when using an EventEmitter?
您可能会这样想,我们正在使用 Angular 构建不会导致任何整页刷新的单页应用程序,我们只更新网站的一部分。
Basically, the application works, but I have to hit F5 to refresh the page after any change is made.
因为无论何时您按下 F5,您的 Angular 应用程序都会重新初始化,从而触发此生命周期挂钩:
ngOnInit() {
this.completetodos = this.completedTodos();
this.incompletetodos = this.incompletedToDos();
}
因此,您的应用程序反映了数据库的最新数据。
One thing to note is that this used to work when I was using an array as a data source, but when I went to json-server and Observables, the page stopped refreshing.
事实上,当您使用数组作为数据源时,我们的应用程序根本不会刷新。这就是所谓的 data-binding,我们在 UI 上看到的数据绑定到 Angular 应用程序持有的数据(在客户端,在客户的记忆)。
在与服务器通信时,当我们对服务器的数据库进行一些更改时,我们必须根据服务器的响应更新客户端的数据。这就是我们在这种情况下在您的待办事项应用程序中的做法。
一旦你完成了 todo 的成功保存,你必须更新 observables
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 对 observables 不起作用,你可以参考下面的 link 将一个新项目追加到 incompletetodos observable 数组中
如果您使用 BehaviorSubject(另一种类型的可观察对象)而不是 Observable,您可以轻松添加新项目。如下所示
incompletetodos: BehaviorSubject<Array<Todo>> = BehaviorSubject.empty<Array<Todo>>();
//你可以像下面这样推送一个新项目
incompletetodos.next(newTodo)