Angular 12 - 使用 Observable 在数组中显示数据
Angular 12 - display data in an Array using an Observable
大家好社区,
我的 angular 12 项目目前遇到问题:
我想显示一个名为 todos 的数组,其中包含我所有的对象变量。但是即使我可以在控制台上看到我的对象正在添加到数组中:todos,似乎有问题(可能是我的 observable),因为它们没有显示在 html 页面上。
我有 2 个组件“add-todo”和“todos”以及 1 个服务“todoService”。
这是我的代码:
//todo.service.ts :
import { Injectable } from '@angular/core';
import {Todo} from '../models/todo.model';
import {Subject} from "rxjs"
@Injectable({
providedIn: 'root'
})
export class TodoService {
todos:Todo[]=[];
todoSubject=new Subject <Todo[]>()
constructor() {
setTimeout(()=>{
this.todos=[
{
firstname:"Youssef"
},
{
firstname:"Yacine"
},
{
firstname:"Ismail"
},
];
this.emitTodo();
},3000)
}
addTodo(todo:Todo):void{
this.todos.push(todo);
this.emitTodo();
console.log("Dans todoservice :"+this.todos);
}
emitTodo():void{
this.todoSubject.next(this.todos);
}
}
//todos.component.ts :
import { Component,OnInit,OnDestroy } from '@angular/core';
import {TodoService} from '../services/todo.service';
import {Todo} from '../models/todo.model';
import {Subscription} from 'rxjs'
@Component({
selector: 'app-todo',
templateUrl: './todo.component.html',
styleUrls: ['./todo.component.css']
})
export class TodoComponent implements OnInit, OnDestroy {
todos;
todoSub;
constructor(private todoService:TodoService){}
ngOnInit():void{
this.todoSub=this.todoService.todoSubject.subscribe(
(value:Todo[])=>{
this.todos=value;
console.log("Dans todo value :"+value);
},
(error)=>{
console.log("Erreur "+error)
},
()=>{
console.log("Observable complete");
}
)
}
ngOnDestroy():void{
this.todoSub.unsubscribe();
}
}
//todos.component.html :
<div class="form-group" *ngFor="let todo of todos;">
{{todo|json}}
</div>
<p>todo works!</p>
//and finally,
//add-todo.component.ts :
import { Component, OnInit } from '@angular/core';
import { Todo } from '../models/todo.model';
import {TodoService} from '../services/todo.service';
import {Router} from '@angular/router';
@Component({
selector: 'app-app-todo',
templateUrl: './app-todo.component.html',
styleUrls: ['./app-todo.component.css']
})
export class AppTodoComponent implements OnInit {
todo=new Todo();
constructor(private todoService:TodoService, private router:Router) { }
ngOnInit(): void {
}
onSubmit():void{
this.todoService.addTodo(this.todo);
console.log("Dans add-todo :"+this.todo);
this.router.navigate(["todos"]);
}
}
add-todo.component.html :
<p>{{todo|json}}</p>
<form #addTodoForm="ngForm" (ngSubmit)="onSubmit()">
<label for="name">Firstname :</label>
<input type="text" name="firstname" [(ngModel)]="todo.firstname" required>
<button type="submit" class="btn btn-success" [disabled]="addTodoForm.invalid">Add Todo</button>
</form>```
This is what it shows when I "ng serve" the code :
[![todos.component.html][1]][1]
Then I add a new todo :
[![add-todo.component.html][2]][2]
Then it redirects to the todos.component.html again but it doesn't display all the todos like before :
[![todos.component.html][3]][3]
[1]: https://i.stack.imgur.com/5P1NQ.png
[2]: https://i.stack.imgur.com/diIDX.png
[3]: https://i.stack.imgur.com/PgKxE.png
我认为您需要不可变地更改 Angular(或任何库或框架)中的数组和对象,以便进行更改检测。
对象和数组是引用类型,因此它们存储它们的内存位置,并且对它们执行推送不会更改它们的内存位置。
每次您想更改 Angular 中的数组和对象时,请以不可变的方式进行(分配新值以便内存中的位置发生变化并进行更改检测)。 maps
可能不需要,但我添加了它们,因此数组内的对象在内存中也有新位置。
addTodo(todo:Todo):void{
// this.todos.push(todo);
this.todos = [...this.todos.map(todo => ({ ...todo })), todo];
this.emitTodo();
console.log("Dans todoservice :"+this.todos);
}
emitTodo():void{
this.todoSubject.next([...this.todos.map(todo => ({ ...todo })]);
}
大家好社区,
我的 angular 12 项目目前遇到问题:
我想显示一个名为 todos 的数组,其中包含我所有的对象变量。但是即使我可以在控制台上看到我的对象正在添加到数组中:todos,似乎有问题(可能是我的 observable),因为它们没有显示在 html 页面上。
我有 2 个组件“add-todo”和“todos”以及 1 个服务“todoService”。
这是我的代码:
//todo.service.ts :
import { Injectable } from '@angular/core';
import {Todo} from '../models/todo.model';
import {Subject} from "rxjs"
@Injectable({
providedIn: 'root'
})
export class TodoService {
todos:Todo[]=[];
todoSubject=new Subject <Todo[]>()
constructor() {
setTimeout(()=>{
this.todos=[
{
firstname:"Youssef"
},
{
firstname:"Yacine"
},
{
firstname:"Ismail"
},
];
this.emitTodo();
},3000)
}
addTodo(todo:Todo):void{
this.todos.push(todo);
this.emitTodo();
console.log("Dans todoservice :"+this.todos);
}
emitTodo():void{
this.todoSubject.next(this.todos);
}
}
//todos.component.ts :
import { Component,OnInit,OnDestroy } from '@angular/core';
import {TodoService} from '../services/todo.service';
import {Todo} from '../models/todo.model';
import {Subscription} from 'rxjs'
@Component({
selector: 'app-todo',
templateUrl: './todo.component.html',
styleUrls: ['./todo.component.css']
})
export class TodoComponent implements OnInit, OnDestroy {
todos;
todoSub;
constructor(private todoService:TodoService){}
ngOnInit():void{
this.todoSub=this.todoService.todoSubject.subscribe(
(value:Todo[])=>{
this.todos=value;
console.log("Dans todo value :"+value);
},
(error)=>{
console.log("Erreur "+error)
},
()=>{
console.log("Observable complete");
}
)
}
ngOnDestroy():void{
this.todoSub.unsubscribe();
}
}
//todos.component.html :
<div class="form-group" *ngFor="let todo of todos;">
{{todo|json}}
</div>
<p>todo works!</p>
//and finally,
//add-todo.component.ts :
import { Component, OnInit } from '@angular/core';
import { Todo } from '../models/todo.model';
import {TodoService} from '../services/todo.service';
import {Router} from '@angular/router';
@Component({
selector: 'app-app-todo',
templateUrl: './app-todo.component.html',
styleUrls: ['./app-todo.component.css']
})
export class AppTodoComponent implements OnInit {
todo=new Todo();
constructor(private todoService:TodoService, private router:Router) { }
ngOnInit(): void {
}
onSubmit():void{
this.todoService.addTodo(this.todo);
console.log("Dans add-todo :"+this.todo);
this.router.navigate(["todos"]);
}
}
add-todo.component.html :
<p>{{todo|json}}</p>
<form #addTodoForm="ngForm" (ngSubmit)="onSubmit()">
<label for="name">Firstname :</label>
<input type="text" name="firstname" [(ngModel)]="todo.firstname" required>
<button type="submit" class="btn btn-success" [disabled]="addTodoForm.invalid">Add Todo</button>
</form>```
This is what it shows when I "ng serve" the code :
[![todos.component.html][1]][1]
Then I add a new todo :
[![add-todo.component.html][2]][2]
Then it redirects to the todos.component.html again but it doesn't display all the todos like before :
[![todos.component.html][3]][3]
[1]: https://i.stack.imgur.com/5P1NQ.png
[2]: https://i.stack.imgur.com/diIDX.png
[3]: https://i.stack.imgur.com/PgKxE.png
我认为您需要不可变地更改 Angular(或任何库或框架)中的数组和对象,以便进行更改检测。
对象和数组是引用类型,因此它们存储它们的内存位置,并且对它们执行推送不会更改它们的内存位置。
每次您想更改 Angular 中的数组和对象时,请以不可变的方式进行(分配新值以便内存中的位置发生变化并进行更改检测)。 maps
可能不需要,但我添加了它们,因此数组内的对象在内存中也有新位置。
addTodo(todo:Todo):void{
// this.todos.push(todo);
this.todos = [...this.todos.map(todo => ({ ...todo })), todo];
this.emitTodo();
console.log("Dans todoservice :"+this.todos);
}
emitTodo():void{
this.todoSubject.next([...this.todos.map(todo => ({ ...todo })]);
}