同步执行 angular_如何在Angular中执行CRUD操作

同步执行 angular

by Zafar Saleem

通过Zafar Saleem

如何在Angular中执行CRUD操作 (How to perform CRUD operations in Angular)

As you may have seen in my previous blog, it is possible to make CRUD operations in vanilla JavaScript. However, it can be a hard decision to choose vanilla JavaScript as it gets messier at some point. Moreover, adding event listeners to dynamically added DOM elements is a pain, as we saw. It gets even more complicated for large-scale projects.

正如您在我以前的博客中可能看到的那样 ,可以使用普通JavaScript进行CRUD操作。 但是,选择香草JavaScript可能会比较困难,因为它有时会变得更加混乱。 而且,正如我们所看到的,将事件侦听器添加到动态添加的DOM元素中是一种痛苦。 对于大型项目,它变得更加复杂。

One solution is to use modern frameworks such as Angular, React, and so on. This blog post is based on the same concept as the previous example, but using Angular.

一种解决方案是使用现代框架,例如Angular,React等。 这篇博客文章基于与上一个示例相同的概念,但是使用Angular。

This blog assumes that you already installed Angular-cli on your machine. Once you have it, then create a new application using the below command.

本博客假定您已经在计算机上安装了Angular-cli。 一旦有了它,然后使用以下命令创建一个新的应用程序。

ng new ngTodo

Wait for a few seconds once the project is created, and then cd into this project. The first thing we need is to create a new component using the below command.

项目创建后,请等待几秒钟,然后将其插入cd。 我们需要做的第一件事是使用以下命令创建一个新组件。

ng generate component todo

This will create a folder with the name todo inside the src/app folder. This folder consists of todo.component.ts, todo.component.html, todo.component.css and todo.component.spec.ts files.

这将在src / app文件夹中创建一个名为todo的文件夹。 该文件夹由todo.component.ts,todo.component.html,todo.component.css和todo.component.spec.ts文件组成。

All of the JavaScript will be written in the .ts file. Actually the TypeScript template code (that is why the file extension is .ts) goes to todo.component.html file, the styles to todo.component.css, and todo.component.spec.ts is for tests.

所有JavaScript都将写入.ts文件。 实际上,TypeScript模板代码(这就是文件扩展名为.ts的原因)转到todo.component.html文件,todo.component.css和todo.component.spec.ts的样式用于测试。

To get started, the first thing that needs to be done is to add this component inside “app.component.html” file like so:

首先,首先要做的是将这个组件添加到“ app.component.html”文件中,如下所示:

<app-todo></app-todo>

Now when you run “ng serve” and load the app in the browser, the todo component will be loaded.

现在,当您运行“ ng serve”并在浏览器中加载应用程序时,todo组件将被加载。

Now it’s time to head over to the todo.component.ts file.

现在是时候转到todo.component.ts文件了。

There should be some boilerplate code written by angular-cli. All of our code goes inside the TodoComponent class.

应该有一些用angular-cli编写的样板代码。 我们所有的代码都放在TodoComponent类中。

import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-todo',
templateUrl: './todo.component.html',
styleUrls: ['./todo.component.css']
})
export class TodoComponent implements OnInit {
constructor() { }
ngOnInit() { }
}

Let’s first explain the above boilerplate code. First we import the Component decorator and OnInit interface from the Angular core. Below is the definition of a decorator.

让我们首先解释上面的样板代码。 首先,我们从Angular核心导入Component装饰器和OnInit接口。 以下是装饰器的定义。

Decorator marks a class as an Angular component and allows us to set configuration metadata that determines how the component should be processed, instantiated, and used at runtime.
装饰器将类标记为Angular组件,并允许我们设置配置元数据,该配置元数据确定应如何在运行时处理,实例化和使用该组件。

Whereas

鉴于

Interface is a lifecycle hook that is called after Angular has initialized all data-bound properties of a directive. Define an ngOnInit()method to handle any additional initialization tasks.

接口是生命周期挂钩,在Angular初始化指令的所有数据绑定属性后调用。 定义ngOnInit()方法来处理任何其他初始化任务。

Then we are exporting the TodoComponent class to make it available for import in the rest of the project. For this example we will only need this component to be imported in app.module.ts to initiate the component.

然后,我们将导出TodoComponent类,以使其可在项目的其余部分中导入。 对于此示例,我们只需要将该组件导入app.module.ts中即可启动该组件。

Since we created this component using angular-cli, that part is already taken care of. If you look into the app.module.ts file, you will see the TodoComponent class is imported and added to the declarations array. Let’s add some code now.

由于我们使用angular-cli创建了此组件,因此该部分已经得到了解决。 如果查看app.module.ts文件,您将看到TodoComponent类已导入并添加到声明数组中。 现在添加一些代码。

Just like our previous example, add a mockData property to the class like below.

就像我们前面的示例一样,向下面的类添加一个mockData属性。

import { Component, OnInit } from '@angular/core';
@Component({  selector: 'app-todo',  templateUrl: './todo.component.html',  styleUrls: ['./todo.component.css']})export class TodoComponent implements OnInit {
// mockData array the includes list of objects with items  mockData: any = [    {      id: '1',      title: 'Buy Milk.',      done: false,      date: new Date()    }, {      id: '2',      title: 'Meeting with Ali.',      done: false,      date: new Date()    }, {      id: '3',      title: 'Tea break.',      done: false,      date: new Date()    }, {      id: '4',      title: 'Go for a run.',      done: false,      date: new Date()    }  ];
constructor() { }
ngOnInit() { }
}

As you can see, we also added the type “any” to mockData. TypeScript brings strictly type functionality to JavaScript, but in this case that really does not matter. If you leave that part from it, it should still be fine.

如您所见,我们还向“ mockData ”添加了“ any”类型。 TypeScript为JavaScript带来了严格的类型功能,但是在这种情况下,这实际上并不重要。 如果您将其保留下来,那应该还是可以的。

Let’s add some more properties to this class which will be used later.

让我们为该类添加更多属性,稍后将使用。

import { Component, OnInit } from '@angular/core';
@Component({  selector: 'app-todo',  templateUrl: './todo.component.html',  styleUrls: ['./todo.component.css']})export class TodoComponent implements OnInit {
mockData: any = [    {      id: '1',      title: 'Buy Milk.',      done: false,      date: new Date()    }, {      id: '2',      title: 'Meeting with Ali.',      done: false,      date: new Date()    }, {      id: '3',      title: 'Tea break.',      done: false,      date: new Date()    }, {      id: '4',      title: 'Go for a run.',      done: false,      date: new Date()    }  ];
// properties to show hide edit form, set updated value and id.  show: boolean = false;  value: string;  id: number;
constructor() {}
ngOnInit() { }
}

The show property is used to show editForm, the value property is used to set the value of edit title, whereas id is used to assign the id of the currently edited item. We will see this later.

show属性用于显示editForm, value属性用于设置编辑标题的值,而id用于分配当前编辑的项目的ID。 我们稍后会看到。

Before going into further discussion, let’s add an html template that we are going to use.

在进行进一步讨论之前,让我们添加一个将要使用的html模板。

<div class="sections">  <div class="edit-popup" *ngIf="show">    <input type="text" name="" class="edit-item" value="{{value}}" #item>    <button class="btn-update" (click)="update(item.value)">Update</button>  </div>
<input type="text" name="" class="item" #item>  <button class="btn-add-item" (click)="create(item.value)">Add</button>
<ul>    <li *ngFor="let item of mockData">      <span [ngClass]="{'done': item.done}">{{item.title}}</span>      <button (click)="remove(item.id)">Delete</button>      <button (click)="edit(item.id, item.title)">Edit</button>      <button (click)="setTaskComplete(item.id)">Complete</button>    </li>  </ul></div>

This is where a bunch of differences can be seen. The first thing that is noticeable is “edit-popup”. It has an *ngIf conditional directive which shows and hides this piece of html code based on the value of “show” which is either true or false. That is the property that comes from the TodoComponent we setup earlier.

在这里可以看到很多差异。 值得注意的第一件事是“编辑弹出窗口”。 它有一个* ngIf条件指令 ,该指令根据true或false的“ show”值显示和隐藏这段html代码。 这是我们之前设置的TodoComponent的属性。

Then simply put the value (title) using {{}} braces inside the input text field. Finally add a click event which will call the update function and pass the value of the input field as an argument.

然后,只需在输入文本字段中使用{{}}大括号将值(标题)放入即可。 最后,添加一个click事件,该事件将调用update函数,并将输入字段的值作为参数传递。

Then there’s the ul list which shows all items. As you can see, the li element has *ngFor which is a repeater directive. It loops through mockData and inside it we access the current object and display its title.

然后是显示所有项目的ul列表。 如您所见,li元素具有* ngFor ,这是一个repeater指令 。 它循环模拟数据,并在其中访问当前对象并显示其标题。

The [ngClass] directive adds the done class to the li item based on the value of done and property of the item. If it is true, add the done class which puts line-trough on the li item to indicate that this task was achieved.

[ngClass]指令根据完成的值和项目的属性将完成的类添加到li项目。 如果为true,则添加完成类,该类将线形放在li项上以指示已完成此任务。

It also has its buttons which are Delete, Edit and Complete buttons. And each of them has click events which call its respective function and pass the current item’s id. In the edit function alongside id, the title is also passed as an argument.

它还具有其按钮,分别是“删除”,“编辑”和“完成”按钮。 每个按钮都有点击事件,这些事件调用其各自的函数并传递当前项目的ID。 在id旁边的edit函数中,标题也作为参数传递。

So that’s it for the template. Let’s head back to the TodoComponent. Here we do not need any render function which we had in vanilla JavaScript.The mockData list and *ngFor directive do the job for rendering. So the R part of CRUD is done. Run the angular server using “ng serve” and load the application in your browser. You should have similar results like below:

模板就是这样。 让我们回到TodoComponent。 在这里,我们不需要香草JavaScript中的任何渲染功能。mockData列表和* ngFor 指令可以完成渲染工作。 因此,CRUD的R部分已完成。 使用“ ng serve”运行角度服务器,然后将应用程序加载到浏览器中。 您应该有类似的结果,如下所示:

Let’s now create the function which is the C in CRUD.

现在让我们在CRUD中创建C函数。

import { Component, OnInit } from '@angular/core';
@Component({  selector: 'app-todo',  templateUrl: './todo.component.html',  styleUrls: ['./todo.component.css']})export class TodoComponent implements OnInit {
mockData: any = [    {      id: '1',      title: 'Buy Milk.',      done: false,      date: new Date()    }, {      id: '2',      title: 'Meeting with Ali.',      done: false,      date: new Date()    }, {      id: '3',      title: 'Tea break.',      done: false,      date: new Date()    }, {      id: '4',      title: 'Go for a run.',      done: false,      date: new Date()    }];
show: boolean = false;  value: string;  id: number;
constructor() {}
// Create function to create new item.  create(item) {    this.mockData.push({      id: Date.now(),      title: item,      done: false,      date: new Date()    });  }
ngOnInit() { }
}

The Create function is triggered when the ADD button is clicked from the template. This is very easy to understand and follow. First, it accesses the mockData array using the this keyword and pushes a new object with appropriate properties (like id, title, done and date etc). This will do the job.

从模板中单击添加按钮时,将触发创建功能。 这是非常容易理解和遵循的。 首先,它使用this关键字访问mockData数组,并推送具有适当属性(例如id,title,done和date等)的新对象。 这样就可以了。

Refresh your browser and type “This is a new item” and press the ADD button — you’ll get a similar result to the above.

刷新浏览器并输入“ This is a new item”,然后按ADD按钮-您将获得与上述类似的结果。

Now let’s continue to the remove/delete function which is the D part of CRUD.

现在,让我们继续执行删除/删除功能,它是CRUD的D部分。

import { Component, OnInit } from '@angular/core';
@Component({  selector: 'app-todo',  templateUrl: './todo.component.html',  styleUrls: ['./todo.component.css']})export class TodoComponent implements OnInit {
mockData: any = [    {      id: '1',      title: 'Buy Milk.',      done: false,      date: new Date()    }, {      id: '2',      title: 'Meeting with Ali.',      done: false,      date: new Date()    }, {      id: '3',      title: 'Tea break.',      done: false,      date: new Date()    }, {      id: '4',      title: 'Go for a run.',      done: false,      date: new Date()    }  ];
show: boolean = false;  value: string;  id: number;
constructor() {}
create(item) {    this.mockData.push({      id: Date.now(),      title: item,      done: false,      date: new Date()    });  }
// delete/remove function goes here.  remove(id) {    this.mockData = this.mockData.filter(item => {      if (item.id !== id) {        return item;      }    });  }
ngOnInit() { }
}

Again very simple. Filter through mockData and find the current element using the item’s id that is to be deleted and the id of the current element from mockData. And return all the items except the one that matches this element.

再次非常简单。 通过mockData筛选,找到使用商品的ID从mockData当前元素的id当前元素将被删除。 并返回除与该元素匹配的项以外的所有项。

Refresh your browser and delete the first item from the list. It should be deleted from the screen as below:

刷新浏览器,然后从列表中删除第一项。 应该从屏幕上将其删除,如下所示:

For update, again, it’s the same as the vanilla JavaScript example: edit is part of two steps. First show the edit form, and second update the item. First let’s show the edit form which is “edit-popup”:

同样,对于更新,它原始JavaScript示例相同 :编辑是两个步骤的一部分。 首先显示编辑表单,然后更新项目。 首先让我们展示一下“ edit-popup”的编辑形式:

import { Component, OnInit } from '@angular/core';
@Component({  selector: 'app-todo',  templateUrl: './todo.component.html',  styleUrls: ['./todo.component.css']})export class TodoComponent implements OnInit {
mockData: any = [    {      id: '1',      title: 'Buy Milk.',      done: false,      date: new Date()    }, {      id: '2',      title: 'Meeting with Ali.',      done: false,      date: new Date()    }, {      id: '3',      title: 'Tea break.',      done: false,      date: new Date()    }, {      id: '4',      title: 'Go for a run.',      done: false,      date: new Date()    }  ];
show: boolean = false;  value: string;  id: number;
constructor() {}
create(item) {    this.mockData.push({      id: Date.now(),      title: item,      done: false,      date: new Date()    });  }
remove(id) {    this.mockData = this.mockData.filter(item => {      if (item.id !== id) {        return item;      }    });  }
// this function does the same as renderEditForm in previous blog.  edit(id, title) {    this.show = true;    this.value = title;    this.id = id;  }
ngOnInit() { }
}

The above function simply sets some TodoComponent attributes — that is, set this.show to true which displays the form. Set the value of this.value to the item’s title that is to be updated, and set this.id to the item’s id. All these attributes can then be accessed in the template and we can use them accordingly.

上面的函数只是设置了一些TodoComponent属性-即,将this.show设置为true来显示表单。 将this.value的值设置为要更新的项目标题,并将this.id设置为项目的ID。 然后,可以在模板中访问所有这些属性,我们可以相应地使用它们。

Now press the EDIT button for the first item and you should be able to see the edit form appear at the top of the page:

现在,对第一项按下EDIT按钮,您应该能够看到编辑表单出现在页面顶部:

Now it’s time to write the update function that actually performs update operations — this is the U part of CRUD.

现在是时候编写实际执行更新操作的更新函数了-这是CRUD的U部分。

import { Component, OnInit } from '@angular/core';
@Component({  selector: 'app-todo',  templateUrl: './todo.component.html',  styleUrls: ['./todo.component.css']})export class TodoComponent implements OnInit {
mockData: any = [    {      id: '1',      title: 'Buy Milk.',      done: false,      date: new Date()    }, {      id: '2',      title: 'Meeting with Ali.',      done: false,      date: new Date()    }, {      id: '3',      title: 'Tea break.',      done: false,      date: new Date()    }, {      id: '4',      title: 'Go for a run.',      done: false,      date: new Date()    }  ];
show: boolean = false;  value: string;  id: number;
constructor() {}
create(item) {    this.mockData.push({      id: Date.now(),      title: item,      done: false,      date: new Date()    });  }
remove(id) {    this.mockData = this.mockData.filter(item => {      if (item.id !== id) {        return item;      }    });  }
edit(id, title) {    this.show = true;    this.value = title;    this.id = id;  }
// function that performs update   update(title) {    this.mockData.map(item => {      if (item.id === this.id) {        item['title'] = title;      }    });
this.show = false;  }
ngOnInit() { }
}

This function gets the title, that is the value of the updated input text field, as an argument. Then map through mockData and place a check to find the item that needs to be updated based on its id. Once found, replace the title property with the edited one and set this.show to false to hide the edit form.

此函数将标题(即更新后的输入文本字段的值)作为参数。 然后通过模拟数据进行映射并进行检查以根据其ID查找需要更新的项目。 找到后,将title属性替换为已编辑的title属性,并将this.show设置为false以隐藏编辑表单。

With this part, when you press the UPDATE button, after entering the updated title you should see the updated title like this:

对于这一部分,当您按下UPDATE按钮时,在输入更新的标题后,您应该看到如下所示的更新的标题:

The final part is to mark the task as done, which function is below.

最后一部分是将任务标记为已完成,其功能如下。

import { Component, OnInit } from '@angular/core';
@Component({  selector: 'app-todo',  templateUrl: './todo.component.html',  styleUrls: ['./todo.component.css']})export class TodoComponent implements OnInit {
mockData: any = [    {      id: '1',      title: 'Buy Milk.',      done: false,      date: new Date()    }, {      id: '2',      title: 'Meeting with Ali.',      done: false,      date: new Date()    }, {      id: '3',      title: 'Tea break.',      done: false,      date: new Date()    }, {      id: '4',      title: 'Go for a run.',      done: false,      date: new Date()    }  ];
show: boolean = false;  value: string;  id: number;
constructor() {}
create(item) {    this.mockData.push({      id: Date.now(),      title: item,      done: false,      date: new Date()    });  }
remove(id) {    this.mockData = this.mockData.filter(item => {      if (item.id !== id) {        return item;      }    });  }
edit(id, title) {    this.show = true;    this.value = title;    this.id = id;  }
update(title) {    this.mockData.map(item => {      if (item.id === this.id) {        item['title'] = title;      }    });
this.show = false;  }
setTaskComplete(id) {    this.mockData.map(item => {      if (item.id === id) {        item['done'] = true;      }    });  }
ngOnInit() {  }
}

This does pretty much the same stuff: map through mockData and find the item to be set as done based on id, and set its done property to true.

这样做的作用几乎相同:通过模拟数据进行映射,并根据id找到要设置为完成的项目,并将其done属性设置为true。

Finally, add some CSS in the todo.component.css file below.

最后,在下面的todo.component.css文件中添加一些CSS。

.done {  text-decoration: line-through;}

The above CSS adds a line-through to any element that has the done class, in this case tasks that are completed.

上面CSS在具有完成类的任何元素(在这种情况下为已完成的任务)中添加了一个直通。

After this, press a couple of Complete buttons and you should see something similar like this:

之后,按几个“完成”按钮,您应该看到类似以下内容:

You can see the difference between this example and the previous one using vanilla JavaScript. Angular allows us to write an approach that’s easy to understand, maintain and scale. This is beneficial in large scale applications. Vanilla JavaScript does the job, but really gets complicated once the application grows.

您可以使用香草JavaScript看到此示例与上一个示例之间的区别。 Angular允许我们编写一种易于理解,维护和扩展的方法。 这在大规模应用中是有益的。 Vanilla JavaScript可以完成这项工作,但是一旦应用程序扩展,它实际上就会变得复杂。

To get all the code written in this example, go ahead and clone the below repository.

要获取此示例中编写的所有代码,请继续并克隆以下存储库。

https://github.com/zafar-saleem/ngTodo

https://github.com/zafar-saleem/ngTodo

翻译自: https://www.freecodecamp.org/news/crud-operations-in-angular-536e1c03a715/

同步执行 angular

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值