AOT - Angular 6 - 指令 SomeComponent,期望0个参数,但实际得到1个。针对自制组件。

54

我在使用以下的包版本时,尝试对当前项目进行AOT编译时遇到了问题:

  • @ngtools/webpack@6.0.3
  • @angular@latest (6.0.2)
  • Webpack@4.0.0

这里可以找到我的webpack和tsconfig.json配置

我遇到了一些与模板中使用的private/protected范围以及一些不真正需要它的函数所提供的某些提取参数(例如,未在EventBinding中使用的$event)相关的问题。

现在我有了以下列表,但是我无法找到我的问题所在:

/path/to/app/header/main-header/main-header.component.html(85,7): : 指令TableOfContentComponent,期望0个参数,但实际上得到了1个。 (1,1): : 指令TableOfContentComponent,期望0个参数,但实际上得到了1个。

我的main-header.component.html文件包含:

// main-header.component.ts
@ViewChildren('headerItems') public headerItems: QueryList<HeaderItemAbstract>;
mainMenuStates = {
    hamburger: false,
    bookmarks: false,
    search: false,
    toc: false,
    medias: false,
    article: false,
    language: false    
};

而我的 TableOfContentComponent 并不包含任何 @Input 属性。

@Component({
    selector: 'ps-table-of-content-template',
    templateUrl: './table-of-content.component.html',
    animations: [slideUpAndDownAnimation]
})
export class TableOfContentComponent extends HeaderItemAbstract implements OnInit {

    toc: TableOfContentModel[];

    devices: DevicesModel;

    tocContentHeight: number;
    tocContentMargin: number;
    menuHeight: string;


    constructor(private tableOfContentService: TableOfContentService,
                private deviceService: DeviceService,
                private elemRef: ElementRef) {
        super();
        this.toc = this.tableOfContentService.tableOfContent;
    }
}

/path/to/app/header/main-header/hamburger-menu/hamburger-menu.component.html(125,5)::指令SliderComponent,期望0个参数,但实际得到了1个。 (1,1)::指令SliderComponent,期望0个参数,但实际得到了1个。

我的hamburger-menu.component.html与上面呈现的代码非常相似:

<ps-slider-component [template]="slidable" [countItems]="associatedDocuments.length">
    <ng-template #slidable>
        <ul class="clearfix">
            <li class="ps-hmt-associated-item-wrapper pull-left slider-item"
                *ngFor="let document of associatedDocuments">
                <a href="{{ document.link }}" target="_blank" class="btn-nostyle">
                    <div class="ps-hmt-image">
                        <img src="{{ document.images.thumbnail }}" alt="">
                    </div>
                    <p class="ps-hmt-title slider-text"
                        [matTooltip]="isArticleView ? null : document.title"
                        [matTooltipPosition]="'above'"
                        [matTooltipClass]="['ps-mat-tooltip', 'ps-mat-tooltip-doc']"
                    >
                        {{ document.title }}
                    </p>
                </a>
            </li>
        </ul>
    </ng-template>
</ps-slider-component>
// On ts side
associatedDocuments: Array<AssociatedDocumentModel>;
@ViewChild('slidable') slidable: ElementRef;

我的SliderComponent长这样:

export class SliderComponent extends UnsubscribeHelper implements OnInit, OnChanges {

    @Input() template: ElementRef;
    @Input() countItems: number;
    @Input() resetSlide ?: null;
    @Input() fixedHeight?: null;
    @Input() isVariableWidth?: null;
    @Input() isBookmarks?: null;
    @Input() hasSkeleton?: boolean = false;

/path/to/app/header/main-header/medias/dialogs/image-dialog.component.html(34,5): : 指令CarouselComponent预期有0个参数,但实际上传入了1个。 (1,1): : 指令CarouselComponent预期有0个参数,但实际上传入了1个。

这个问题和前一个非常接近,我认为问题是一样的。

/path/to/app/document/page/page.component.html(7,9): : 指令InfinityPageScrollComponent预期有0个参数,但实际上传入了1个。 (1,1): : 指令InfinityPageScrollComponent预期有0个参数,但实际上传入了1个。

在这里我们没有任何关于InfinityPageScrollComponent的输入,而标签的调用方式是这样的:<ps-infinity-page-scroll></ps-infinity-page-scroll>

我特别说明一下,当我在我的webpack上禁用AOT时,所有的东西都能正常工作。

我尝试在AoT Do's and Don'ts中找到解决方案,但没有任何结果。

我还注意到,如果我禁用fullTemplateTypeCheck,我会遇到大约18,000个错误,其中一些是隐含的任何类型和更奇怪的是,在构造函数中声明的服务的未定义属性。

--- EDIT 1: 提供抽象类UnsubscribeHelper的代码 ---

export abstract class HeaderItemAbstract extends UnsubscribeHelper implements AfterViewInit {
    public toggleItem: string = 'out';
    public ANIMATION_DURATION = slideUpAndDownAnimationDuration;

    constructor() {
        super();
    }

    // [Some other method]
    /**
     * Self animate after loading on DOM
     */
    ngAfterViewInit()
    {
        // Wait next to to avoid error :
        // ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked
        setTimeout(() => {
            this.toggleAnimation();
        },100);
    }
}

抽象类UnsubscribeHelper的代码:

export abstract class UnsubscribeHelper implements OnDestroy {

    subscriptions: Subscription[] = [];

    ngOnDestroy() {
        this.subscriptions.forEach(sub => sub.unsubscribe());
    }

    addSubscription(subscription: Subscription) {
        this.subscriptions.push(subscription);
    }
}

1
你可以提供一下你的超类HeaderItemAbstract的代码吗? - user4676340
1
@trichetriche 确定,我已经添加了我需要的两个抽象类。 - Yanis-git
1
谢谢。为了可读性,我建议您删除项目的配置,因为问题与您的类有关(我正在尝试找到它们)。 - user4676340
1
是的,是正确的。我会将其移到Pastebin上。 - Yanis-git
1
tableOfContentServiceDeviceService 是否被装饰器 @Injectable() 所修饰? - user4676340
显示剩余3条评论
4个回答

197

我准备了一个最小化、完整化和可验证化的示例

我注意到使用@HostListner时缺少了一个参数

以下是问题的示例:

@HostListener('window:resize', ['$event'])
onResize(): void {
    
}

只需删除'$event',它就能很好地工作。

总之,这两个选项都能正常工作:

// When you need the Event variable, you can use following syntax.
@HostListener('window:resize', ['$event'])
onResize($event: Event): void {
    
}

// When you do not need the Event variable, you can use following syntax.
@HostListener('window:resize')
onResize(): void {
    
}

感谢 @trichetriche 的帮助。


5
这让我节省了很多时间。编译器不会告诉我问题出在哪里,这太奇怪而且不准确了。再次感谢。 - Koscik
1
因为注解在AOT编译中没有很好地集成,所以很难注意到这一点 :) - Yanis-git
2
我在做正确的Google搜索之前浪费了两个小时。我真的想不出哪个参数是不被期望的!!!谢谢!!圣诞节快乐!! - Sampgun
3
那么这个事件将如何起作用?删除事件会构建,但在需要窗口对象等场景中无法工作...因此,解决方案可以是在调用函数时添加事件参数,即使您不需要使用它。请注意,不要改变原文的意思。 - TheDoozyLulu
2
请注意:如果您在@Component装饰器选项的host输入中定义了侦听器,那么当然也会出现此错误:@Component({host: {'click': 'handleClick($event)'}}) - derpedy-doo
显示剩余6条评论

38

我遇到了一个类似的错误,称为ERROR in (1,1): : Directive SomeComponent, Expected 0 arguments, but got 1.,正如这个评论中所描述的那样:https://dev59.com/-lUL5IYBdhLWcg3waHRw#50409526, 但现在它出现在了window:scroll

@HostListener('window:scroll', ['$event']) public onScroll(): void {
  ...
}

这不是很明显,因为在组件内部定义的指令(@HostListener)类似于匿名指令,而且不太清楚我需要在哪里搜索它。

我通过逻辑解决了这个问题:如果我们向调用onScroll函数提供$event - 我们需要在这里设置参数event,像这样:onScroll(event),因此在HostListener指令的函数处理程序中没有参数,我们收到了这个错误。

但是在我的情况下,它发生在第1行,如错误消息中所述,但@HostListener是在所有函数声明之后声明的,并且通过提升和优化,它可能出现在第1行。

解决方案代码:

@HostListener('window:scroll', ['$event']) public onScroll(event /*provide $event to method here */): void {
  ...
}

2
@HostListener是一个指令。它的方法没有参数,但隐式需要它。将事件(event)参数设置为该方法并解决问题 :) - Igor Kurkov
5
好的,它可以工作了,但我刚刚从HostListener中删除了$event参数。现在它可以正常工作。 - Shareef
1
谢谢你的回答。这个答案比得票最多的那个更好,因为它告诉你为什么会出现这个异常。 - hehe
1
太棒了!这就是帮助我的答案。谢谢你。 - Marko Francekovic
我认为这应该是答案,而且它对我也起作用了。而被选中的那个没有,因为我需要在我的方法中使用事件。 - taleb
这应该是被接受的答案。 - ismaestro

1
我添加了一个额外的答案,希望能帮助其他遇到相同错误信息但不同问题的人。在我的情况下,我在基类中重写方法的签名有所不同。
export class Foo extends BaseFoo {

   // NOTE: Missing (parameter)
   onBlur() {
      this.touched();
   }
}

export class BaseFoo {
    onBlur(target: any) {
        ...
    }
 }

然后在同一个组件中,我在模板中缺少了参数:

<div tabindex="0" (blur)="onBlur()>...</>

0

我在Angular 8中遇到了相同的错误。

1>> 我将它升级到9,并在项目中进行了很多配置更改,但未解决问题。

2>> 我在StackOverflow和GitHub上进行了所有更改,但未解决问题。

对于我来说,一个内部交叉库@HostListenerangular2-multiselect-dropdown(您可以在npm上轻松找到它)。

它会出现错误,例如Directive ɵc,期望2个参数,但只有1个

(有时AOT编译它,但大多数情况下不会) 但每次我运行命令npm run build:ssr

最终,在花费了一天以上的时间后,我删除了这个库(angular2-multiselect-dropdown),现在所有问题都已解决


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接