优秀的编程知识分享平台

网站首页 > 技术文章 正文

你可以在你的项目中使用5个Angular 的指令

nanyue 2024-10-24 11:50:07 技术文章 2 ℃

在这个帖子中,我们将学习如何使用指令将特定的行为添加到DOM中的元素并在我们的应用程序中重用这种行为。

获得高级管理人员手册的重要趋势、技巧和战略,以竞争和赢得数字经济。

在最近的一篇文章中,我们展示了一些我们在代码库中使用的角管的例子。现在,我们来谈谈指令。角度指示允许您将行为附加到DOM中的元素,并在项目中重用它。该框架已经提供了许多方便的指令,如NgStyle、NgIf、NgFor和NgSwitch。

到目前为止,我们已经编写了超过65个定制的指令,并且愿意分享我们认为在您的项目中会有用的前五项。请注意,下面演示中的指令是为了清晰起见而特意提取的,并且没有广泛的自定义选项或析构/清除代码。用它们作为起点。

1、调出

实际上,没有任何应用程序没有callout或工具提示,这是一个小的弹出元素,提供了更多关于它们的所有者的细节。

下面是一个callout指令的最小示例,当您将鼠标悬停在一个元素上时,它会动态地创建带有指定文本的callout组件:

这个演示中使用的CalloutComponent创建动态usingviewContainer.createComponent(),当鼠标离开元素被毁。这里,我们在将该指令应用到的元素(这是注入的ViewContainerRef点)之后立即插入callout。要获得更详细的配置选项,请参阅我们之前关于构建角组件的文章。

2、深度禁用

在较大的应用程序中,当状态发生变化时,禁用整个UI元素组并不少见。例如,Lucidchart编辑器根据当前选择的形状动态启用和禁用某些工具组:

Lucidchart编辑器的片段显示了一个带有一些按钮组的工具栏。

Lucidchart编辑器的片段。由于选择了一个块,所以禁用了行选项。

我们可以创建一个特殊的禁用指令,它将从父组件中的一个级联下来,而不是在每个单独的组件上重复禁用状态的表达式。

我们的原型:

这里的大部分“魔法”实际上是由角的依赖注入框架完成的:

class DisabledDirective {

constructor(

@SkipSelf() @Optional() private optParent: DisabledDirective

) {...}

}

该指令的构造函数中的这条线表示“注入最近的父类的失效指令,如果有的话,跳过我自己。”现在,在变更检测周期中,我们不仅要检查当前指令的布尔值,还要检查父节点:

newValue = !!this.appDisabled || this.optParent.disabled;

在实现该指令之后,我们将更新我们的组件的代码,比如表单字段和按钮,以了解它(再次使用依赖注入机制)。

@Component({

selector: 'app-button',

template: `

<button [disabled]="disabled"><ng-content></ng-content></button>

`

})

export class ButtonComponent {

private disabledDirective: DisabledDirective;

constructor(changeDetector: ChangeDetectorRef, @Optional() optDisabled: DisabledDirective) {

this.disabledDirective = resolve(optDisabled);

this.disabledDirective.onChange(this, (newValue) => {

changeDetector.markForCheck();

});

}

get disabled(): boolean {

return this.disabledDirective.disabled;

}

}

虽然这个指令很简单,但它减少了代码重复,并允许我们在多个级别上切换UI的区域,而不需要在组件之间进行任何显式的通信。

我们还添加了通过disabledStopPropagation属性禁用在select元素(如上面的演示中的Fullscreen按钮)中禁用的级联的能力。

3、动画编辑

*ngIf可能是最广泛使用的内置角指令之一。但是如果我们想用动画来切换应用程序中的组件呢?下面的指令扩展了ngIf以支持动画。

该指令简单地切换了容器元素上的显示和隐藏类,并假设动画是通过CSS实现的,它提供了很大的灵活性——你不必去触摸指令代码来改变动画。

private hide() {

let container = this.getContainer();

if (!!container) {

container.classList.remove('showing');

container.classList.add('hiding');

animationEndSafe(container, 1000).then(() => {

this.ngIf = this.visible;

container.classList.remove('hiding');

});

this.animatedIfOnHide.emit();

}

}

这个演示实现了一个简单的淡出动画,但它可以很容易地调整为滑动或增长/缩小或任何组合。animationEndSafe函数只是一个侦听器的包装器,它是一个在指定超时后调用回调的animationend事件,如果事件没有被触发的话。这是为了确保代码不会被“卡住”,以防容器元素没有定义在它上面的任何动画。

4、窗口大小调整阈值

CSS3媒体查询(技术上称为媒体特性)大大简化了web开发人员的响应设计,允许我们根据屏幕大小、方向和像素密度等特性改变页面布局。然而,在角度世界中,应用程序的UI呈现的一个重要部分被框架接管了。

下面的指令允许您定义一系列窗口宽度的“断点”,并在阈值发生转换时更改模板。

该指令通过方便的主机绑定监听窗口的调整事件:

@Directive({

selector: '[appWindowResize]',

host: {

'(window:resize)': 'onResize()',

}

})

唯一值得一提的其他技术问题是,当您在侦听可能频繁发生的DOM事件(如resize或鼠标移动)时,请确保将事件处理程序排除掉,以便它不会执行过多的次数,从而造成不必要的CPU负载。许多第三方库都包含一个debounce函数,但是我们在演示中包括了我们的实现:

// Callback debounce utility

function debounce<F extends(...args: any[]) => void>(f: F, timeout: number, target?: any): F {

let timer: number|undefined = undefined;

return (function(this: any, ...args: any[]) {

target = target || this;

timer && clearTimeout(timer);

timer = setTimeout(() => {

f.apply(target, args);

}, timeout);

}) as F;

}

private onResize = debounce(() => {

const offsetWidth = this.getWidth();

...

}, 200);

5、Focus

在HTML5规范中有一个自动对焦属性,用于在页面加载时自动聚焦表单字段。例如,这为开发人员提供了一种简单的方法,可以将登录表单集中在页面上,这样就可以节省访问者在输入字段之前点击输入字段的时间。然而,这个属性在一个可以动态构建DOM的角度应用程序中不起作用。这个指令相当于自动对焦属性的角度。

您在项目中经常使用的指令是什么?在评论中分享。

Tags:

最近发表
标签列表