0

在本教程中

https://www.sitepoint.com/practical-guide-angular-directives/

我正在学习如何创建自定义指令。我按照下面发布的代码中所示的步骤操作,但是尽管添加了前面提到的网站中解释的确切代码,但当我运行命令时

ng serve --open

我得到了如下图所示的东西。请让我知道为什么 myCustomIf 不起作用。我说 myCustomIf 不起作用,因为我在 localhost:4200 上得到的东西如发布的图片所示

请让我知道如何使 myCustomIf 按照上面发布的链接中的教程中的说明工作

app.component.ts

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

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'ngDirective1';
  name = 'Angular';
  condition = false;    

}

app.myCustomeIfDirective.ts

import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core';

@Directive({
    selector: '[myCustomIf]'
})
export class MyCustomeIfDirective{
    constructor(private templateRef: TemplateRef<any>,private viewContainer: ViewContainerRef){ }

    @Input()
    setMyCustomIf(condition : boolean) {
        if(condition) {
            this.viewContainer.createEmbeddedView(this.templateRef);
        } else {
            this.viewContainer.clear();
        }
    }
}

应用程序模块

import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core';

@Directive({
    selector: '[myCustomIf]'
})
export class MyCustomeIfDirective{
    constructor(private templateRef: TemplateRef<any>,private viewContainer: ViewContainerRef){ }

    @Input()
    setMyCustomIf(condition : boolean) {
        if(condition) {
            this.viewContainer.createEmbeddedView(this.templateRef);
        } else {
            this.viewContainer.clear();
        }
    }
}

app.component.html

<h1 my-error>Hello {{name}}</h1>
<h2 *myCustomIf="condition">Hello {{name}}</h2>
<button (click)="condition = !condition">Click</button>

图片

在此处输入图像描述

4

2 回答 2

0

如果您打开控制台,它应该显示如下:

NG0303:无法绑定到“myCustomIf”,因为它不是“h2”的已知属性

Angular 结构指令,用简短的语法(with *)编写并接受一个或多个输入,必须具有@Input与指令的属性选择器同名的结构指令),例如:

@Directive({
    selector: '[anyAttr]'
})
export class MyCustomeIfDirective{
    @Input()
    anyAttr: any;

或者

@Directive({
    selector: '[anotherAttr]'
})
export class MyCustomeIfDirective{
    @Input()
    set anotherAttr(val: any) {}

为什么会这样?

那是因为*ngIf它只是扩展版本的快捷方式:

<ng-template [ngIf]="...">...

或者

*anyAttr => <ng-template [anyAttr]="...">...

现在,让我们看看您的代码:

@Directive({
    selector: '[myCustomIf]'
})
export class MyCustomeIfDirective{
    @Input()
    setMyCustomIf(condition : boolean) {

需要注意的几点:

  • setMyCustomIf在您的情况下只是一种方法
  • 如果将其转换为 setterset MyCustomIf则不MyCustomIf匹配myCustomIf,因为 js 区分大小写。

解决方案是:

@Input()
set myCustomIf(condition : boolean) {

Ng 运行示例

于 2021-04-02T05:04:21.210 回答
0

在您的指令(app.myCustomeIfDirective.ts)中,您需要将输入的名称与指令的名称相匹配(因为条件是通过该属性传递的):

@Input("myCustomIf")
set myCustomIf(condition : boolean) {
    if(condition) {
        this.viewContainer.createEmbeddedView(this.templateRef);
    } else {
        this.viewContainer.clear();
    }
}

(请注意,您还可以更改函数的名称以匹配指令名称)

stackblitz演示

于 2021-04-02T07:19:59.840 回答