[英]Angular @Input decorator and other issues
我正在按照 Google Codelabs 上的教程制作 Kanban-fire 應用程序。 這是我面臨問題的部分的鏈接。 https://developers.google.com/codelabs/building-a-web-app-with-angular-and-firebase#10
我正在使用 Angular CLI 11.0.7、節點 12.18.2、Ubuntu 20.10 64 位、Z558B544CF685F39D38B67E4903E39C.3
正如本教程中所解釋的,我跟隨並進行了所有必要的更改。 這是我面臨的問題。
起初,我收到了這個錯誤
屬性“任務”沒有初始化程序,也沒有在構造函數中明確分配。 19 任務:任務;
這是我對應的代碼
@Input() task: Task;
它使用以下任務接口
export interface Task {
id?: string;
title: string;
description: string;
}
我嘗試通過將@Input 中的任務屬性初始化為
@Input() task: Task = {title: 'def title', description: 'def desc'};
在出現這些錯誤之前一切都很好。
正如您在我分享的鏈接中看到的那樣,我們必須對app.component.html
以及app.component.ts
文件中的一些方法進行更改。 我進行了更改,現在我收到了這些錯誤。
Error: src/app/app.component.html:21:34 - error TS2345: Argument of type 'CdkDragDrop<{ id: string; }[] | null, any>' is not assignable to parameter of type 'CdkDragDrop<Task[], Task[]>'.
Type '{ id: string; }[] | null' is not assignable to type 'Task[]'.
Type 'null' is not assignable to type 'Task[]'.
21 (cdkDropListDropped)="drop($event)"
和
Error occurs in the template of component AppComponent.
src/app/app.component.html:27:17 - error TS2739: Type '{ id: string; }' is missing the following properties from type 'Task': title, description
27 cdkDrag [task]="task"></app-task>
為了完整的參考,我在這里提供app.component.html
以及app.component.ts
代碼
<mat-toolbar color="primary">
<mat-icon>local_fire_department</mat-icon>
<span>Kanban Fire</span>
</mat-toolbar>
<div class="content-wrapper">
<button (click)="newTask()" mat-button>
<mat-icon>add</mat-icon> Add Task
</button>
</div>
<div class="container-wrapper">
<div class="container">
<h2>Backlog</h2>
<mat-card
cdkDropList
id="todo"
#todoList="cdkDropList"
[cdkDropListData]="todo | async"
[cdkDropListConnectedTo]="[doneList, inProgressList]"
(cdkDropListDropped)="drop($event)"
class="list">
<p class="empty-label" *ngIf="(todo | async)?.length === 0">Empty List</p>
<app-task
(edit)="editTask('todo', $event)"
*ngFor="let task of todo | async"
cdkDrag [task]="task"></app-task>
</mat-card>
</div>
<div class="container">
<h2>In Progress</h2>
<mat-card
cdkDropList
id="inProgress"
#inProgressList="cdkDropList"
[cdkDropListData]="inProgress | async"
[cdkDropListConnectedTo]="[todoList, doneList]"
(cdkDropListDropped)="drop($event)"
class="list">
<p class="empty-label" *ngIf="(inProgress | async)?.length === 0">Empty List</p>
<app-task
(edit)="editTask('inProgress', $event)"
*ngFor="let task of inProgress | async"
cdkDrag [task]="task"></app-task>
</mat-card>
</div>
<div class="container">
<h2>Done</h2>
<mat-card
cdkDropList
id="done"
#doneList="cdkDropList"
[cdkDropListData]="done | async"
[cdkDropListConnectedTo]="[todoList, inProgressList]"
(cdkDropListDropped)="drop($event)"
class="list">
<p class="empty-label" *ngIf="(done | async)?.length === 0">Empty List</p>
<app-task
(edit)="editTask('done', $event)"
*ngFor="let task of done | async"
cdkDrag [task]=""></app-task>
</mat-card>
</div>
</div>
app.component.ts
import { Component } from '@angular/core';
import { Task } from '../app/task/task';
import { CdkDragDrop, transferArrayItem } from '@angular/cdk/drag-drop';
import { MatDialog } from '@angular/material/dialog';
import { TaskDialogComponent } from '../app/task-dialog/task-dialog.component';
import { TaskDialogResult } from '../app/task-dialog/task-dialog.component';
import { AngularFirestore } from '@angular/fire/firestore';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
todo = this.store.collection('todo').valueChanges({ idField: 'id' });
inProgress = this.store.collection('inProgress').valueChanges({ idField: 'id' });
done = this.store.collection('done').valueChanges({ idField: 'id' });
constructor(private dialog: MatDialog, private store: AngularFirestore) {}
editTask(list: 'done' | 'todo' | 'inProgress', task: Task): void {
const dialogRef = this.dialog.open(TaskDialogComponent, {
width: '270px',
data: {
task,
enableDelete: true,
}
});
dialogRef.afterClosed().subscribe((result: TaskDialogResult) => {
if (result.delete) {
this.store.collection(list).doc(task.id).delete();
} else {
this.store.collection(list).doc(task.id).update(task);
}
});
}
drop(event: CdkDragDrop<Task[]>): void {
if (event.previousContainer === event.container) {
return;
}
const item = event.previousContainer.data[event.previousIndex];
this.store.firestore.runTransaction(() => {
const promise = Promise.all([
this.store.collection(event.previousContainer.id).doc(item.id).delete(),
this.store.collection(event.container.id).add(item),
]);
return promise;
});
transferArrayItem(
event.previousContainer.data,
event.container.data,
event.previousIndex,
event.currentIndex
);
}
newTask(): void {
const dialogRef = this.dialog.open(TaskDialogComponent, {
width: '270px',
data: {
task: {}
}
});
dialogRef.afterClosed().subscribe((result: TaskDialogResult) => {
this.store.collection('todo').add(result.task)
});
}
}
任何幫助將不勝感激。
感謝@Eliseo 指出這一點。 開啟嚴格模式導致這一切發生。
只需在tsconfig.json
文件中將strict
和strictTemplates
標志設置為 false。
我正在處理的應用程序中遇到了類似的問題。 我最終密切注意與您類似的錯誤消息...您的錯誤消息是-->“屬性'任務'沒有初始化程序,並且未在構造函數中明確分配。19 任務:任務;
在我的情況下,我的錯誤是 -->"Property 'election' has no initializer 並且沒有在 constructor.ts(2564) 中明確分配"
我的輸入語句是
@Input() election: Election
我在我的構造函數中添加了這一行,該構造函數以前沒有填充這個初始化。
this.election =ELECTIONS[0]
這解決了我的問題
我想您必須在構造函數中進行初始化,無論您要導入什么。
總結源組件-->
elections-main-list.component.html
<app-election-item
*ngFor="let election of elections"
[election]="election" >
</app-election-item>
導入組件
election-item-component.ts
export class ElectionItemComponent implements OnInit{
@Input() election: Election
constructor() {
this.election =ELECTIONS[0]
}
As I have only been using Angular for a short period of time the lesson I learned was to pay close attention to the error message. anyway this solution worked perfectly and on the next step....
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.