Sådan udføres CRUD-operationer i vinkel

Som du måske har set i min tidligere blog, er det muligt at foretage CRUD-operationer i vanilje JavaScript. Det kan dog være en hård beslutning at vælge vanilje JavaScript, da det bliver mere rodet på et eller andet tidspunkt. Desuden er det en smerte, som vi så, at tilføje begivenhedslyttere til dynamisk tilføjede DOM-elementer. Det bliver endnu mere kompliceret for store projekter.

En løsning er at bruge moderne rammer som Angular, React osv. Dette blogindlæg er baseret på det samme koncept som det foregående eksempel, men bruger Angular.

Denne blog antager, at du allerede har installeret Angular-cli på din maskine. Når du har det, skal du oprette en ny applikation ved hjælp af nedenstående kommando.

ng new ngTodo

Vent et par sekunder, når projektet er oprettet, og cd derefter ind i dette projekt. Den første ting, vi har brug for, er at oprette en ny komponent ved hjælp af kommandoen nedenfor.

ng generate component todo

Dette opretter en mappe med navnet todo inde i src / app-mappen. Denne mappe består af todo.component.ts, todo.component.html, todo.component.css og todo.component.spec.ts filer.

Alt JavaScript vil blive skrevet i .ts-filen. Faktisk går TypeScript-skabelonkoden (det er grunden til filtypen .ts) til todo.component.html-filen, typografierne todo.component.css og todo.component.spec.ts er til test.

For at komme i gang er det første, der skal gøres, at tilføje denne komponent i filen "app.component.html" som sådan:

Nu når du kører “ng serve” og indlæser appen i browseren, indlæses todo-komponenten.

Nu er det tid til at gå over til filen todo.component.ts.

Der skal være en kogepladekode skrevet af angular-cli. Al vores kode går ind i TodoComponent-klassen.

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() { }
}

Lad os først forklare ovenstående kedelpladekode. Først importerer vi Component decorator og OnInit interface fra Angular core. Nedenfor er definitionen af ​​en dekoratør.

Dekoratør markerer en klasse som en kantet komponent og giver os mulighed for at indstille konfigurationsmetadata, der bestemmer, hvordan komponenten skal behandles, instantieres og bruges under kørsel.

Der henviser til

Interface er en livscykluskrog, der kaldes efter, at Angular har initialiseret alle databasede egenskaber i et direktiv. Definer en ngOnInit()metode til at håndtere yderligere initialiseringsopgaver.

Derefter eksporterer vi klassen TodoComponent for at gøre den tilgængelig til import i resten af ​​projektet. I dette eksempel behøver vi kun at importere denne komponent i app.module.ts for at starte komponenten.

Da vi oprettede denne komponent ved hjælp af vinkel-cli, er den del allerede taget hånd om. Hvis du kigger ind i filen app.module.ts , vil du se, at klassen TodoComponent importeres og føjes til erklæringsarrayet. Lad os tilføje noget kode nu.

Ligesom vores tidligere eksempel skal du tilføje en mockData- egenskab til klassen som nedenfor.

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() { }
}

Som du kan se, tilføjede vi også typen "enhver" til mockData . TypeScript bringer nøjagtig typefunktionalitet til JavaScript, men i dette tilfælde betyder det ikke noget. Hvis du forlader den del fra den, skal den stadig være i orden.

Lad os tilføje nogle flere egenskaber til denne klasse, som vil blive brugt senere.

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() { }
}

Det viser egenskab bruges til at vise editForm, at værdien er ejendom, der anvendes til at angive værdien af redigere titel, hvorimod id bruges til at tildele den id for det aktuelt redigerede element. Vi vil se dette senere.

Før vi går i yderligere diskussion, skal vi tilføje en html-skabelon, som vi skal bruge.

 Update 
 Add

    
  • {{item.title}} Delete Edit Complete

Det er her, en række forskelle kan ses. Den første ting, der er synlig, er “rediger-popup”. Det har et * ngIf- betinget direktiv, der viser og skjuler dette stykke html-kode baseret på værdien af ​​"show", som enten er sand eller falsk. Det er den egenskab, der kommer fra TodoComponent, vi konfigurerede tidligere.

Derefter skal du blot placere værdien (titel) ved hjælp af {{}} seler i indtastningstekstfeltet. Endelig tilføj en klikhændelse, der kalder opdateringsfunktionen og videregiver værdien af ​​indtastningsfeltet som et argument.

Så er der ul-listen, der viser alle emner. Som du kan se, har li-elementet * ngFor, som er et repeaterdirektiv . Det løber gennem mockData, og indeni det får vi adgang til det aktuelle objekt og viser dets titel.

[NgClass] -direktivet føjer den færdige klasse til li-varen baseret på værdien af ​​gjort og ejendom af varen. Hvis det er sandt, skal du tilføje den færdige klasse, der sætter linjetrug på li-elementet for at indikere, at denne opgave blev opnået.

Det har også sine knapper, som er Slet-, Rediger- og Komplet-knapper. Og hver af dem har klikhændelser, der kalder dens respektive funktion og videregiver det aktuelle artikels id. I redigeringsfunktionen sammen med id sendes titlen også som et argument.

Så det er det for skabelonen. Lad os gå tilbage til TodoComponent. Her har vi ikke brug for nogen gengivelsesfunktion, som vi havde i vanille JavaScript. MockData- listen og * ngFor direktiv gør jobbet til gengivelse. Så R-delen af ​​CRUD er færdig. Kør vinkelserveren ved hjælp af "ng serve" og indlæs applikationen i din browser. Du skal have lignende resultater som nedenfor:

Lad os nu oprette den funktion, som er C i CRUD.

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() { }
}

Opret-funktionen udløses, når der klikkes på knappen TILFØJ fra skabelonen. Dette er meget let at forstå og følge. Først får den adgang til mockData- arrayet ved hjælp af dette nøgleord og skubber et nyt objekt med passende egenskaber (som id, titel, færdig og dato osv.). Dette vil gøre jobbet.

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

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

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.

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”:

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.

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:

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

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.

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

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.

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

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

Ovenstående CSS tilføjer en gennemgang til ethvert element, der har den færdige klasse, i dette tilfælde opgaver, der er afsluttet.

Efter dette skal du trykke på et par komplette knapper, og du skal se noget lignende som dette:

Du kan se forskellen mellem dette eksempel og det foregående ved hjælp af vanille JavaScript. Vinkel giver os mulighed for at skrive en tilgang, der er let at forstå, vedligeholde og skalere. Dette er fordelagtigt i store applikationer. Vanilla JavaScript gør jobbet, men bliver virkelig kompliceret, når applikationen vokser.

For at få al koden skrevet i dette eksempel, gå videre og klon nedenstående lager.

//github.com/zafar-saleem/ngTodo