跳至主要內容
版本:v8

建置錯誤

常見錯誤

忘記裝飾器的括號

裝飾器在註解後應加上括號 ()。一些範例包含:@Injectable()@Optional()@Input() 等。

@Directive({
selector: 'my-dir',
})
class MyDirective {
// Wrong, should be @Optional()
// @Optional does nothing here, so MyDirective will error if parent is undefined
constructor(@Optional parent: ParentComponent) {}
}

常見錯誤

無法解析所有參數

Cannot resolve all parameters for 'YourClass'(?). Make sure that all the parameters are decorated with Inject or have valid type annotations and that 'YourClass' is decorated with Injectable.

此例外狀況表示 Angular 對於 YourClass 的建構子的一個或多個參數感到困惑。為了執行依賴注入,Angular 需要知道要注入的參數類型。您需要藉由指定參數的類別來讓 Angular 知道此資訊。請確保

  • 您正在匯入參數的類別。
  • 您已正確註解參數或指定其類型。
import { MyService } from 'my-service'; // Don't forget to import me!

@Component({
template: `Hello World`,
})
export class MyClass {
// service is of type MyService
constructor(service: MyService) {}
}

有時程式碼中的循環參照會導致此錯誤。循環參照表示兩個物件互相依賴,因此無法在彼此之前宣告它們。為了避免這種情況,我們可以運用 Angular 內建的 forwardRef 函式。

import { forwardRef } from '@angular/core';

@Component({
selector: 'my-button',
template: `<div>
<icon></icon>
<input type="button" />
</div>`,
directives: [forwardRef(() => MyIcon)], // MyIcon has not been defined yet
}) // forwardRef resolves as MyIcon when MyIcon is needed
class MyButton {
constructor() {}
}

@Directive({
selector: 'icon',
})
class MyIcon {
constructor(containerButton: MyButton) {} // MyButton has been defined
}

ParamType 沒有提供者

No provider for ParamType! (MyClass -> ParamType)

這表示 Angular 知道它應該注入的參數類型,但它不知道如何注入。

如果參數是服務,請確保您已將指定的類別加入至您的應用程式可用的提供者清單中

import { MyService } from 'my-service';

@Component({
templateUrl: 'app/app.html',
providers: [MyService], // Don't forget me!
})
class MyApp {}

如果參數是另一個元件或指令(例如,父元件),將其新增至您的提供者清單將會使錯誤消失,但這將會與上述的提供者的多個實例有相同的效果。您將建立元件類別的新實例,並且不會取得您想要的元件實例的參照。請改為確保您期望注入的指令或元件可供您的元件使用(例如,如果您期望它是父元件,則它實際上是父元件)。這可能是用範例來理解會最容易

@Component({
selector: 'my-comp',
template: '<p my-dir></p>',
directives: [forwardRef(() => MyDir)],
})
class MyComp {
constructor() {
this.name = 'My Component';
}
}

@Directive({
selector: '[my-dir]',
})
class MyDir {
constructor(c: MyComp) {
// <-- This is the line of interest

// Errors when directive is on regular div because there is no MyComp in the
// component tree so there is no MyComp to inject
console.log("Host component's name: " + c.name);
}
}

@Component({
template:
'<my-comp></my-comp>' + // No error in MyDir constructor, MyComp is parent of MyDir
'<my-comp my-dir></my-comp>' + // No error in MyDir constructor, MyComp is host of MyDir
'<div my-dir></div>', // Errors in MyDir constructor
directives: [MyComp, MyDir],
})
class MyApp {}

以下圖表說明可用的注入器

                 +-------+
| App |
+---+---+
|
+-------------+------------+
| |
+------+------+ +--------+--------+
| Div (MyDir) | | MyComp (MyDir) | <- MyComp can be injected
+-------------+ +--------+--------+
^ |
No MyComp to inject +------+------+
| P (MyDir) | <- MyComp can be injected from parent
+-------------+

為了擴展先前的範例,如果您並不總是期望元件/指令參照,則可以使用 Angular @Optional 註解

@Directive({
selector: '[my-dir]',
})
class MyDir {
constructor(@Optional() c: MyComp) {
// No longer errors if c is undefined
if (c) {
console.log(`Host component's name: ${c.name}`);
}
}
}

無法繫結至 'propertyName',因為它不是已知的屬性

Can't bind to 'propertyName' since it isn't a known property of the 'elementName' element and there are no matching directives with a corresponding property

當您嘗試繫結沒有該屬性的元素上的屬性時,就會發生這種情況。如果該元素是元件或在其上具有一個或多個指令,則該元件或指令都沒有該屬性。

<!-- div doesn't have a 'foo' property -->
<div [foo]="bar"></div>

ControlContainer 沒有提供者

No provider for ControlContainer! (NgControlName -> ControlContainer)

此錯誤是上述 沒有提供者 錯誤的更具體版本。當您使用像是 NgControlName 的表單控制項,而未指定父NgForm 或 NgFormModel 時,就會發生這種情況。在大多數情況下,可以藉由確保您的表單控制項位於實際的表單元素中來解決此問題。NgForm 使用 form 作為選擇器,因此這會執行個體化新的 NgForm

@Component({
template:
'<form>' +
'<input ngControl="login">' +
'</form>'
})

找不到元件工廠

No component factory found for <component name>

當您嘗試使用尚未匯入並新增至您的 ngModule 的元件、提供者管道或指令時,就會發生此錯誤。每當您將新的元件、提供者、管道或指令新增至您的應用程式時,都必須將其新增至 src/app/app.module.ts 檔案中的 ngModule,Angular 才能夠使用它。為了修正此錯誤,您可以將違規的元件、提供者、管道或指令匯入至 app.module 檔案中,然後,如果它是提供者,請將其新增至 providers 陣列,而對於元件、管道或指令,則請將其新增至 declarations 陣列和 entryComponents 陣列。