typescript 如何使用Angular 服务将表单值从一个组件传递到另一个组件中的列表?

thtygnil  于 2022-11-26  发布在  TypeScript
关注(0)|答案(2)|浏览(157)

我一直在尝试开发一个待办事项列表项目。我有四个组件:每日、项目列表、项目和添加任务日志x1c 0d1x
daily组件包含一个表单和一个显示表单中的值的列表。
以下是代码:

每日.服务.ts

此服务代码用于从表单中获取值并将其添加到列表中。

import { Injectable } from '@angular/core';
import { BehaviorSubject, Observable } from 'rxjs';
import { DailyTask } from './models';

@Injectable({ providedIn: 'root' })
export class DailyService {

private _dailies$ = new BehaviorSubject<DailyTask[]>([]); 
public getDailies(): DailyTask[] {
return this._dailies$.getValue();
}

public setDailies(data: DailyTask[]): void {
 this._dailies$.next(data);
}

public getDailiesObservable(): Observable<DailyTask[]> {
return this._dailies$.asObservable();
}

public createTask(newTask: string): void{

console.log( "check");

  const dailyTask: DailyTask = { task: newTask, type: 'DAILY' };
  this.setDailies([dailyTask, ...this.getDailies()])
 }
}

每日.组件.Ts

export class DailyComponent implements OnInit {
  public dailyList$: Observable<DailyTask[]> | null = null;

  constructor(private _dailyService: DailyService) {}

  ngOnInit(): void {
    this.dailyList$ = this._dailyService.getDailiesObservable();
  }

  public addDaily(name: string) {
     this._dailyService.createTask(name);
  }
 }

每日.组件.html

<mat-card>
   <h1>Daily</h1>
    <app-item-list
      [type]="'DAILY'"
      [initialData$]="dailyList$"
      [onAddItem]="addDaily.bind(this)"
    ></app-item-list>
 </mat-card>

项目列表.组件.html

<div>
 <mat-form-field appearance="outline">
 <input
  matInput
  placeholder="Add a Task"
  (keyup.enter)="addTask()"
  autocomplete="off"
  [formControl]="nameControl"/>
 </mat-form-field>
</div>

<ng-container *ngIf="filteredData$ | async as data">

<app-item
  [value]="value"
  *ngFor="let value of data; index as index"
  (inputDataChange)="removeTask(data, index)"
>
</app-item>
</ng-container>

项目列表.组件.ts

export class ItemListComponent implements OnInit {
   
   nameControl = new FormControl('');
   @Input() public type: ItemType | null = null;
   @Input() public onAddItem: Function | null = null;
   
   constructor(private _homeService: HomeService) {}
   ngOnInit(): void {}

   addTask() {
     if (this.onAddItem) {
        this.onAddItem(this.nameControl.value);
        this.nameControl.reset();
   }
 }

项目.组件.html

<div class="displayTask">
  <div class="displayvalue" [ngClass]="{ 'line-through': value.task }">
     {{ value.task | uppercase }}
  </div>
</div>

物料.组件.ts

export class ItemComponent implements OnInit {
  @Input()
   value: any;
  constructor() {}
  ngOnInit(): void {}
 }

上面的代码集运行良好,下面的代码用于新组件task-dailog

任务日志.html

<div mat-dialog-title class="dailogHeader">
   <h1 >Create Daily</h1>
</div>

<div mat-dialog-content>
    <div class="dialogContent">
      <p>Task</p>
    <mat-form-field appearance="outline">
    <input
        matInput
        placeholder="Add a new Task"
        autocomplete="off"
        (keyup.enter)="addDailogTask()"
        [formControl]="nameControl"
    />
    </mat-form-field>
    </div>
</div>

任务日志.组件.ts

export class TaskDialogComponent implements OnInit {
  nameControl = new FormControl('');

  constructor(
    public dialogRef: MatDialogRef<TaskDialogComponent>,
    private _dailyService: DailyService,
  ) {}

  ngOnInit(): void {}

  onNoClick(): void {
    this.dialogRef.close();
  }

  addDailogTask(){
    const value$ =   this.nameControl.value;
    this.nameControl.reset();
    console.log(value$);
  }
 }

在task-dialog.component.ts中,我有一个从表单中获取值的函数,但我被困在这里,不知道如何继续。我想学习如何将此表单值从TaskDialogComponent发送到DailyComponent中的列表。
这里也是项目的Stackblitz
有没有人能帮我这个忙。我对棱角相对较新,真的很感激你的帮助。提前感谢!。

1aaf6o9v

1aaf6o9v1#

您需要首先转换窗体值类型,默认情况下,form.value可以作为any返回,这与只需要stringcreateTask函数不匹配

解决方案

addDailogTask() {
  const value$ = this.nameControl.value as string;
  ...
}
eqfvzcg8

eqfvzcg82#

看看这个工作:https://stackblitz.com/edit/github-pdhugz-sbinrb?file=src%2Fapp%2Fadd-task-btn%2Fadd-task-btn.component.ts

  1. task-dialog.component.html有一些问题。基本上,您想要双向系结[工作]输入字段。您必须指定[mat-dialog-close]="task",将对话方块中的数据明确传送到AddTaskBtnComponent中的dialogRef
    1.一旦对话框连接正确..您可以从对话框中获取afterClosed().subscribe方法中的值。

添加任务按钮组件.ts

@Component({
 selector: 'app-add-task-btn',
 templateUrl: './add-task-btn.component.html',
 styleUrls: ['./add-task-btn.component.scss'],
})
export class AddTaskBtnComponent implements OnInit {

  ...

 openDialog(): void {

   const dialogRef = this.dialog.open(TaskDialogComponent, {
   width: '500px',
   height: '500px',
   });

   dialogRef.afterClosed().subscribe((task) => {
     if (task) {
       this.dailyService.createTask(task);
     } 
     console.log('The dialog was closed');
   });
  }
 }
}
  1. MatDialogModule未导入到TaskDialogModule
    我发现您的代码及其结构存在一些问题。

提示:

1.您希望代码的结构与UI的结构相同。这样会更容易使用。例如:

src
  app
  L home
    L shared
      L components
         L item-list
             L components
                L item 
    L components
       L profile-banner
       L searchbar
       L add-task-btn
       L daily
         L components
         L services
           L daily.service.ts
         L ... 
       L todo
       L habits 
    L services
    L models 
    L home.component.ts
    L home.component.scss
    L home.component.html

1.不知道为什么你决定把每个组件放在一个单独的模块中。这在技术上是不必要的,登录页面可以在一个模块中,而主组件中的其他所有内容可以在另一个模块中。这样你就可以懒加载HomeModule了。
1.当你有一个深度嵌套的组件时,我建议使用状态管理库(我使用ngxs),它更容易使用,所以你不必通过@input装饰器传递值。而且它会使你的代码更可读。

相关问题