创建angular组件_使用Angular指令创建拖放文件上传组件

创建angular组件

Recently, during one of my training sessions, one of my trainees working on an Angular project needed to implement a drag and drop file upload component.

最近,在我的一个培训课程中,我的一个在Angular项目中工作的受训人员需要实现拖放文件上传组件。

So as is often the first reflex, they looked for an existing npm package that does the task, but ran into issues with making the new packages feel coherent with the rest of the application’s UI.

因此,就像通常的第一次反射一样,他们寻找可以完成任务的现有npm软件包,但是在使新软件包与应用程序UI的其余部分保持一致方面遇到了问题。

After helping them dig around for a way to customize the CSS however, I had a thought. What if I used this situation as an opportunity to build their understanding of custom directives, and by the same occasion demystify the implementation of such a functionality by showing them they could easily build it themselves? This blog post as basically what we ended up with.

在帮助他们挖掘出一种定制CSS的方法之后,我有了一个想法。 如果我以这种情况为契机来加深他们对自定义指令的理解,并通过向他们展示自己可以很容易地构建它来使这种功能的实现神秘化,那该怎么办? 这篇博文基本上就是我们最终得到的。

So we already had an existing Angular project initialized, but for the sake of this blog post being its own independent thing if you are following through, we will here create a generic app skeleton to demo this.

因此,我们已经初始化了一个现有的Angular项目,但是为了使本博文成为您自己的独立文章,如果您继续进行下去,我们将在此处创建一个通用应用程序框架对此进行演示。

As in my previous blog post I am assuming that you already have the Angular cli installed here. (If not, please check out this guide to install the tooling: Angular — Setting up the local environment and workspace https://angular.io/guide/setup-local )

就像我之前的博客文章一样,我假设您已经在此处安装了Angular cli。 (如果没有,请查看本指南以安装工具:Angular —设置本地环境和工作区https://angular.io/guide/setup-local )

步骤1:建立独立的专案 (Step 1: Creating our standalone project)

Run the following command in your terminal

在终端中运行以下命令

ng new angular-file-upload --style=scss

步骤2:产生一个新指令,其中将包含我们拖放文件上传的逻辑。 (Step 2: Generating a new directive that will contain our logic for the drag and drop file upload.)

Angular directives are functions that enhance the capability of HTML elements by attaching custom behavior to the DOM via custom tags and attributes. What does this mean concretely? Let’s have a look.

Angular指令是通过通过自定义标签和属性将自定义行为附加到DOM来增强HTML元素功能的函数。 具体是什么意思? 我们来看一下。

First we need to change directory to our project folder

首先,我们需要将目录更改为我们的项目文件夹

cd angular-file-upload

Then we can generate our brand new directive using the angular CLI

然后,我们可以使用角度CLI生成全新的指令

ng g directive directives/upload

This shall create the following upload.directive.ts file:

这将创建以下upload.directive.ts文件:

import { Directive } from ‘@angular/core’;@Directive({
selector: ‘[appUpload]’
})export class UploadDirective {constructor() { }}

So basically this class will be our directive. Worthy of note already in that skeleton is the selector in the directive declaration. In a nutshell, this means that any DOM element we attach the “appUpload” attribute to will have additional behaviour that we will defined in this class. We can also change the selector if we wish, but for the purpose of this demo we shall leave it be :)

因此,基本上,此类将是我们的指令。 值得一提的是指令声明中的选择器。 简而言之,这意味着我们将附加“appUpload”属性的任何DOM元素都具有将在此类中定义的其他行为。 如果愿意,我们也可以更改选择器,但是出于演示目的,我们将其保留为:)

步骤3:导入我们需要的作品 (Step 3: Importing the pieces we need)

Part of the beauty of Angular is that the framework comes with many parts already included, so we won’t have any external dependency for this functionality and only use what is provided to us in @angular/core.

Angular的优点之一就是该框架已经包含了许多部分,因此我们对此功能没有任何外部依赖性,仅使用@angular/core.提供给我们的内容@angular/core.

Update the import line in our directive to read as follows:

更新指令中的导入行,内容如下:

import { Directive, Output, EventEmitter, HostBindingDecorator, HostListener } from ‘@angular/core’;

So if we go over the new additions, we now have:

因此,如果我们遍历新增加的内容,则现在有:

  • Output and EventEmitter will be used to provide a hook event our component will be able to subscribe to. This is important since we need the component to be able define what happens when a file is dropped.

    OutputEventEmitter将用于提供我们的组件能够订阅的挂钩事件。 这很重要,因为我们需要组件能够定义删除文件时发生的情况。

  • HostBindingDecorator will allow us to interact with the properties of the DOM element our directive will be attached to. In our case we will interact with the style of the host element

    HostBindingDecorator将允许我们与将附加指令的DOM元素的属性进行交互。 在我们的案例中,我们将与宿主元素的样式进行交互

  • and HostListener will allow us to listen to DOM events from the host element and define how our directive will react to them.

    并且HostListener允许我们侦听host元素中的DOM事件并定义我们的指令如何对它们做出React。

步骤4:定义我们的类属性 (Step 4: Define our Class properties)

Within our Class definition, we will first add three properties using our Output and HostBindingDecorator as follows:

在我们的类定义中,我们将首先使用OutputHostBindingDecorator添加三个属性,如下所示:

@Output() onFileDropped = new EventEmitter<any>();
@HostBinding(‘style.background-color’) public background = ‘#fff’;
@HostBinding(‘style.opacity’) public opacity = ‘1’;

Here we have the properties that will help us control the directive.

在这里,我们具有可以帮助我们控制指令的属性。

  • OnFileDropped will be the custom event that we will expose to our component, thus the output decorator. This will be triggered when a file is dropped on our host DOM element later.

    OnFileDropped将是我们将向组件公开的自定义事件,即输出装饰器。 稍后将文件放到我们的主机DOM元素上时,将触发此操作。

  • background and opacity on the other hand are simple properties that we are binding to the host DOM element’s style property. We are also setting the default “idle” values to a white background and a full opacity.

    另一方面,background和opacity是我们绑定到主机DOM元素的style属性的简单属性。 我们还将默认的“空闲”值设置为白色背景和完全不透明。

As of now, if we try to attach our directive to a DOM element, nothing much will happen, only the element’s background color and opacity will be affected. So now would be the perfect time to add some more behaviour to our directive :)

到目前为止,如果我们尝试将指令附加到DOM元素,则不会发生太多事情,仅会影响该元素的背景颜色和不透明度。 因此,现在是将更多行为添加到指令中的最佳时机:)

步骤5:添加拖动事件 (Step 5: Adding the drag events)

We will now add two methods to our class, which will be event listeners for our dragOver and dragLeave events. In these methods, we will simply change the background and opacity defined above, and prevent those events from bubbling up to our host component.

现在,我们将两个方法添加到类中,这将是我们的dragOverdragLeave事件的事件侦听器。 在这些方法中,我们将简单地更改上面定义的背景和不透明度,并防止这些事件冒泡到我们的宿主组件中。

//Dragover listener, when something is dragged over our host element@HostListener(‘dragover’, [‘$event’]) onDragOver(evt) {
evt.preventDefault();
evt.stopPropagation();
this.background = ‘#9ecbec’;
this.opacity = ‘0.8’
}//Dragleave listener, when something is dragged away from our host element@HostListener('dragleave', ['$event']) public onDragLeave(evt) {
evt.preventDefault();
evt.stopPropagation();
this.background = '#fff'
this.opacity = '1'
}

步骤6:我们的放下事件 (Step 6: Our drop event)

Almost done with the directive! all that’s left is to add our last event listener, for when a file is actually dropped over our host DOM element. Let’s add the following method:

指令几乎完成了! 剩下的就是添加我们的最后一个事件侦听器,用于将文件实际拖放到主机DOM元素上的时间。 让我们添加以下方法:

@HostListener('drop', ['$event']) public ondrop(evt) {
evt.preventDefault();
evt.stopPropagation();
this.background = '#f5fcff'
this.opacity = '1'
let files = evt.dataTransfer.files;
if (files.length > 0) {
this.onFileDropped.emit(files)
}
}

This one is a bit different. Apart from the similar bubbling prevention and style alterations, here we are checking if there are actually files that were dropped on our host DOM element, and if such is the case we emit our custom onFileDropped event that can be subscribed to from our component.

这个有点不同。 除了类似的防止冒泡和样式更改之外,我们还在这里检查是否确实有文件拖放到了主机DOM元素上,如果是这种情况,我们发出了可以从组件中订阅的自定义onFileDropped事件。

We have now completed our directive. here is the complete Class definition:

现在,我们已经完成了指令。 这是完整的类定义:

import { Directive,Output, EventEmitter, HostBinding, HostListener, HostBindingDecorator } from '@angular/core';
@Directive({
selector: '[appUpload]'
})export class UploadDirective {
@Output() onFileDropped = new EventEmitter<any>();
@HostBinding('style.background-color') public background = '#fff';
@HostBinding('style.opacity') public opacity = '1';

//Dragover listener, when something is dragged over our host element
@HostListener('dragover', ['$event']) onDragOver(evt) {
evt.preventDefault();
evt.stopPropagation();
this.background = '#9ecbec';
this.opacity = '0.8'
};
//Dragleave listener, when something is dragged away from our host element
@HostListener('dragleave', ['$event']) public onDragLeave(evt) {
evt.preventDefault();
evt.stopPropagation();
this.background = '#fff'
this.opacity = '1'
}
@HostListener('drop', ['$event']) public ondrop(evt) {
evt.preventDefault();
evt.stopPropagation();
this.background = '#f5fcff'
this.opacity = '1'
let files = evt.dataTransfer.files;
if (files.length > 0) {
this.onFileDropped.emit(files)
}
}
constructor() { }
}

步骤7:使用指令 (Step 7: Using the directive)

Now that our directive has been implemented, we can include it in our component. It can be any component in your app, but for the purpose of this demo we will be using the main app component.

现在,我们的指令已实现,我们可以将其包含在组件中。 它可以是您应用程序中的任何组件,但是出于演示目的,我们将使用主应用程序组件。

In our app.component.html file let’s add the following element:

在我们的app.component.html文件中,添加以下元素:

<div appUpload (onFileDropped)="uploadFile($event)" >Drop a file here</div>

Our final step will be to handle the onFileDropped event within our app.component.ts by defining the uploadFile method.

我们的最后一步将是处理我们内部的onFileDropped事件app.component.ts通过定义uploadFile方法。

uploadFile(evt){
// evt is an array of the file(s) dropped on our div. Here we're assuming only one file has been uploaded

let payload = new FormData();
payload.append('data', evt[0]);
// File can now be uploaded by doing an http post with the payload
}

From there we can proceed with tweaking the UI as desired to fit our requirements :)

从那里我们可以根据需要调整UI,以适应我们的要求:)

During my training sessions, one of my main objectives is to help demystify the implementation of common UI components to my trainees. It has been my observation that Junior devs tend to treat ready-made UI components as black boxes and demonstrating how they themselves could implement such a component from scratch helps them realize the realm of possibilities at their fingertips :)

在我的培训课程中,我的主要目标之一是帮助使我的受训者无法理解常见UI组件的实现。 据我观察,初级开发人员倾向于将现成的UI组件视为黑盒,并演示他们自己如何可以从头开始实现这样的组件,有助于他们实现指尖的可能性:)

I have also added some CSS to make the demo a bit more user friendly. As usual all the code for this demo can be found at: Angular file upload.

我还添加了一些CSS,以使演示更加用户友好。 通常,该演示的所有代码都可以在以下位置找到: Angular file upload

The UI for this demo can be found at Angular upload file.

该演示的UI可以在Angular上传文件中找到。

翻译自: https://medium.com/swlh/creating-a-drag-and-drop-file-upload-component-using-angular-directives-91596ecb65bf

创建angular组件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值