typescript 使用Observable的Array中的Angular 12显示数据

92vpleto  于 2023-01-18  发布在  TypeScript
关注(0)|答案(2)|浏览(158)

大家好!
我的angular 12项目当前遇到一个问题:
我想显示一个名为todos的数组,它包含了我所有的对象变量。然而,即使我可以在控制台上看到我的对象正在被添加到数组中:todos,似乎有一个问题(与我的可观察也许),因为他们没有显示在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
bpzcxfmw

bpzcxfmw1#

我认为您需要在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 })]);
}
vojdkbi0

vojdkbi02#

您正在服务类中存储todos:Todo。然后尝试通过将该服务注入到组件中来访问组件中的todos

constructor(private todoService:TodoService){}

它不会那样工作的。请了解一下依赖注入是如何工作的。
可能的解决方案,
1.可以将数据存储在本地存储或会话存储中,以便在不同的组件中访问它们
1.您可以使用Ngrx之类的数据存储技术(推荐大规模应用)
1.将数据存储在本地文件中(不建议用于大规模应用程序)

相关问题