cmd实用指令
本文重点介绍Angular指令-它们是什么,如何使用它们以及如何构建自己的指令。
指令可能是Angular应用程序中最重要的部分,如果我们考虑一下,最常用的Angular单元即组件实际上就是指令。
Angular组件不只是带有模板的指令。 当我们说组件是Angular应用程序的构建块时,实际上是在说指令是Angular应用程序的构建块。
基本概述
指令的核心是一个函数,只要Angular编译器在DOM中找到指令就执行。 Angular指令用于通过赋予其新语法来扩展HTML的功能。 每个指令都有一个名称-可以是Angular预定义的名称(如ng-repeat
,也可以是可以自定义的名称。 每个指令都决定了可以在哪里使用它:在element
, attribute
, class
或comment
。
默认情况下,从Angular版本2起,Angular指令分为三种不同的类型:
组件
如前所述,组件只是带有模板的指令。 在后台,它们使用指令API,并为我们提供了一种更清晰的定义它们的方法。
其他两种指令类型没有模板。 相反,它们是专门为DOM操作量身定制的。
属性指令
属性指令通过更改其行为和外观来操纵DOM。
我们使用属性指令将条件样式应用于元素,显示或隐藏元素或根据不断变化的属性动态改变组件的行为。
结构指令
这些是专门为创建和销毁DOM元素而量身定制的。
一些属性指令(例如hidden
,显示或隐藏元素)基本上保持了DOM的原样。 但是结构化的Angular指令对DOM的友好度要低得多,因为它们从DOM中添加或完全删除了元素。 因此,在使用它们时,我们必须格外小心,因为实际上是在更改HTML结构。
使用现有的角度指令
在Angular中使用现有指令非常容易,并且如果您过去编写过Angular应用程序,我很确定您已经使用了它们。 ngClass
指令是现有Angular属性指令的一个很好的例子:
<p [ngClass]="{'blue'=true, 'yellow'=false}">
Angular Directives Are Cool!
</p>
<style>
.blue{color: blue}
.yellow{color: yellow}
</style>
因此,通过在下面的示例中使用ngClass
指令 ,我们实际上是将blue
类添加到了我们的段落中,而明确地没有添加yellow
。 由于我们要更改类的外观,而不是更改实际HTML结构,因此这显然是一个属性指令。 但是Angular还提供了现成的结构化指令,例如ngIf
:
@Component({
selector: 'ng-if-simple',
template: `
<button (click)="show = !show">{{show ? 'hide' : 'show'}}</button>
show = {{show}}
<br>
<div *ngIf="show">Text to show</div>
`
})
class NgIfSimple {
show: boolean = true;
}
在此示例中,我们使用ngIf
指令通过按钮添加或删除文本。 在这种情况下,HTML结构本身会受到影响,因此它显然是结构指令。
有关可用Angular指令的完整列表,我们可以查看官方文档 。
如我们所见,使用Angular指令非常简单。 Angular指令的真正力量在于能够创建自己的指令。 Angular提供了一个干净而简单的API来创建自定义指令,这就是我们将在以下各节中介绍的内容。
创建一个属性指令
创建指令类似于创建组件。 但是在这种情况下,我们使用@Directive
装饰器。 对于我们的示例,我们将创建一个名为“ my-error-directive”的指令,该指令将以红色突出显示表示错误的元素的背景。
对于我们的示例,我们将使用Angular 2 quickstart软件包 。 我们只需要克隆存储库,然后运行npm install
和npm start
。 它将为我们提供可用于实验的样板应用程序。 我们将在该样板之上构建示例。
app.myerrordirective.ts
,在src/app
文件夹中创建一个名为app.myerrordirective.ts
的文件,并向其中添加以下代码:
import {Directive, ElementRef} from '@angular/core';
@Directive({
selector:'[my-error]'
})
export class MyErrorDirective{
constructor(elr:ElementRef){
elr.nativeElement.style.background='red';
}
}
免费学习PHP!
全面介绍PHP和MySQL,从而实现服务器端编程的飞跃。
原价$ 11.95 您的完全免费
从@angular/core
导入Directive
,我们可以使用它。 首先,我们需要一个选择器,该选择器为指令指定名称。 在这种情况下,我们称之为my-error
。
最佳实践表明,在命名Angular指令时,我们总是使用前缀。 这样,我们确保避免与任何标准HTML属性发生冲突。 我们也不应使用ng
前缀。 Angular使用了该指令,我们不想将我们自定义创建的Angular指令与Angular预定义指令混淆。 在此示例中,我们的前缀是my-
。
然后,我们创建一个类MyErrorDirective
。 要访问我们DOM的任何元素,我们需要使用ElementRef
。 由于它也属于@angular/core
软件包,因此将其与Directive
一起导入并使用它很简单。
然后,我们添加了代码以突出显示类的构造函数。
为了能够使用这个新创建的指令,我们需要将其添加到app.module.ts
文件的声明中:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { MyErrorDirective } from './app.myerrordirective';
import { AppComponent } from './app.component';
@NgModule({
imports: [ BrowserModule ],
declarations: [ AppComponent, MyErrorDirective ],
bootstrap: [ AppComponent ]
})
export class AppModule { }
最后,我们要利用刚刚创建的指令。 为此,让我们导航到app.component.ts
文件并添加以下内容:
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
template: `<h1 my-error>Hello {{name}}</h1>`,
})
export class AppComponent { name = 'Angular'; }
最终结果类似于以下内容:
创建结构指令
在上一节中,我们看到了如何使用Angular创建属性指令。 创建结构行为的方法完全相同。 我们使用指令的代码创建一个新文件,然后将其添加到声明中,最后在组件中使用它。
对于我们的结构指令,我们将实现ngIf
指令的副本。 这样,我们不仅将实现指令,而且还将了解Angular指令如何处理幕后事情。
让我们从我们的app.mycustomifdirective.ts
文件开始:
import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core';
@Directive({
selector: '[myCustomIf]'
})
export class MyCustomIfDirective {
constructor(
private templateRef: TemplateRef<any>,
private viewContainer: ViewContainerRef) { }
@Input() set myCustomIf(condition: boolean) {
if (condition) {
this.viewContainer.createEmbeddedView(this.templateRef);
} else {
this.viewContainer.clear();
}
}
}
如我们所见,我们为此使用了几个不同的导入,主要是: Input
, TemplateRef
和ViewContainerRef
。 Input
装饰器用于将数据传递到组件。 TemplateRef
用于实例化嵌入视图 。 嵌入式视图表示要渲染的布局的一部分,并且已链接到模板。 最后, ViewContainerRef
是一个容器,可以在其中附加一个或多个视图。 这些组件一起工作如下:
指令通过注入
ViewContainerRef
来访问视图容器。 通过调用ViewContainerRef
的createEmbeddedView
方法并传入模板,可以创建嵌入式视图并将其附加到视图容器。 我们要使用指令附带的模板,所以我们传入注入的TemplateRef
。 —来自Rangle.io的Angular 2培训
接下来,我们将其添加到声明器中:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { MyErrorDirective } from './app.myerrordirective';
import { MyCustomIfDirective } from './app.mycustomifdirective';
import { AppComponent } from './app.component';
@NgModule({
imports: [ BrowserModule ],
declarations: [ AppComponent, MyErrorDirective, MyCustomIfDirective ],
bootstrap: [ AppComponent ]
})
export class AppModule { }
我们在组件中使用它:
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
template: `<h1 my-error>Hello {{name}}</h1>
<h2 *myCustomIf="condition">Hello {{name}}</h2>
<button (click)="condition = !condition">Click</button>`,
})
export class AppComponent {
name = 'Angular';
condition = false;
}
结构指令提供的这种方法可能非常有用,例如,当我们必须根据不同用户的权限向他们显示不同信息时。 例如,站点管理员应该能够查看和编辑所有内容,而普通用户则不能。 如果我们使用属性指令将私有信息加载到DOM中,那么普通用户和所有与此相关的用户都可以访问它。
角度指令:属性与结构
我们已经研究了属性和结构指令。 但是我们什么时候应该使用其中一个?
答案可能令人困惑,我们可能会因为解决了我们的问题而最终选择了错误的答案。 但是有一条简单的规则可以帮助我们选择正确的规则。 基本上,如果在DOM不可见时具有指令的元素在DOM中仍然有用,那么我们绝对应该保留它。 在这种情况下,我们使用诸如hidden
的属性指令。 但是,如果该元素没有用,那么我们应该将其删除。 但是,我们必须小心避免一些常见的陷阱。 我们必须避免因为总是更容易隐藏总是隐藏元素的陷阱。 这将使DOM更加复杂,并可能对整体性能产生影响。 还应避免总是删除和重新创建元素的陷阱。 它绝对更干净,但是会牺牲性能。
总而言之,应仔细分析每种情况,因为理想的解决方案始终是对您的应用程序结构,行为和性能影响最小的解决方案。 该解决方案可能是属性指令,结构指令,或者在最常见的情况下,两者都折衷。
结论
在本文中,我们研究了Angular指令(Angular应用程序的核心)。 我们研究了不同类型的指令,并了解了如何创建适合我们需求的自定义指令。
我希望本文能够帮助您使用Angular指令并开始运行。 如有任何疑问,请随时使用下面的评论部分。
翻译自: https://www.sitepoint.com/practical-guide-angular-directives/
cmd实用指令