nb en en da en en sv sv da et da da da cs da oc da de en da da nb cs nb es en es da da sl en sl da da en da hbs_lat en sv cs tl da en en sv fr de de fr fr fr sv en fr nl fa or ar it fr en en en tr tr da da en en sv fr de de fr fr fr sv or en en en mk ru sk en fr da oc da tl en tl da tl en tl da da da ar en en sv fr de de fr fr en en en en en en en da da da da ar en en en da ar en en sv fr de de fr fr fr sv en fr en ja fr en en en en en en en en en hi en en en en da da ar en en en da en en en sv fr de de fr fr fr sv en en en en en en fi en en es en da da en en en sv fr ru en en da da en en en en da en en en sv fr de de fr fr fr sv en fr en ja fr en ceb en en lt ceb en en lt ceb en en lt ru da da da tl en tl da tl en tl sv tl en tl da en en sv en en sv en es en sv fr de de fr fr fr sv en en en nl es en en es kn da da da en en en en da en en en sv fr de en sv en kn ca en en en en da en en en sv fr de de en hbs_lat en da en da en en en en da en en en en da en en en sv fr de de fr fr fr sv en fr en ja en en en en it en en ceb en es kn en kn da ar hi en sv fr de de fr fr fr sv en fr en ne en en en uk en en en zh en en en de tl en tl da en en en sv fr de de fr fr fr sv en fr en ja en en sv en kn en sv en kn en ru en kn da en en en sv en en da en en en en da en en en sv fr de de fr fr fr sv en fr en ja fr de en en en en en en kn en en ceb en es kn en kn da da ar en en sv fr de de fr fr zh en en en ms en en da tl en tl da en en en sv fr de de fr fr fr sv en fr en ja fr de fr es nb fr de en en en en en ru en hbs_lat en es en en en it en en gu en es kn en kn nb ar en en sv fr de de fr fr fr sv en en en en fr en fr en en de da en en en sv fr de de fr fr fr sv en fr en ja fr de fr es nb fr de en en en ru en ta en fa en en en en en en en kn en en en kn da da ar en en en da ar en en en de da ar en en en en da en en en da en en en en da en en en sv fr de de fr fr fi hbs_lat en hbs_lat de en es en en en en en da en en en sv fr de de fr fr fr sv en fr en ja fr de fr es nb fr de en en sv de de fr en fr it fr ru en fr en en da en tr en de ru tr ru it nl en en en es es en pt en en pt es es es yue es da ar en en en da da da tl en tl sv da tl en tl da en da da ar en en sv fr de de fr fr fr sv en zh en en en ms en en en da da da en en en id en en en sv fr de de fr fr fr sv en en en en fi pt en az yue pt es da da en en en en nb da da da en da da da da da sv da nb nb en da da da da en nl da sv da en
I gang med Angular 6 på Linux – NerdGirl
Forbud fører sjældent noget godt med sig
(Last Updated On: 23. marts 2022)
Informationen i dette indlæg kan være forældet da det omhandler Angular 6. I skrivende stund er Angular 13 på trapperne.
Det fede Angular er at det er så ufattelig nemt at komme i gang. Nedenstående er mine noter fra denne Angular 6 tutorial som jeg varmt kan anbefale.:
Opret en liste og hent data
Marker den aktuelle side i menuen
Først skal vi have fat i Angulars cli (command line interface):
Programmet vi bruger til at installere med (npm) er en del af nodejs. Parameteren -g tilføjer vi for at installere cli’et globalt. Dvs. vi bagefter kan bruge det overalt på computeren.
Efter installationen kan vi skrive Angular cli kommandoer ved at prefikse dem med ng. Det næste vi skal gøre er nemlig at oprette et nyt Angular projekt. Bemærk at du fra nu af benytter de enkelte kommandoer som almindelig bruger:
$ ng new mitProjekt --skip-git --routing --style scss --prefix mp
Erstat “mitProjekt” med dit eget projektnavn. Bemærk at navnet lige pt. hverken kan indeholde tal, bindestreg eller understreg. Du kan også tilføje --style scss (default er almindelig css). Det er en fordel hvis du f.eks. tilføjer Bootstrap da det gør det nemt at integrere og overskrive de default værdier Bootstrap kommer med. Jeg tilføjer --routing fordi mit projekt har sider med forskellige adresser (url’er) og denne parameter hjælper med at oprette en routnings-fil. Flaget --prefix hjælper til at undgå navnekollisioner med andres moduler hvis du deler dit projekt.
Jeg har desuden tilføjet --skip-git ganske enkelt fordi jeg bruger subversion. I know. It’s sooo old 😉
Følgende kommando kompilerer og åbner projektet i din browser, forudsat at du befinder dig i projektets mappe :
package.json indeholder navn og versionsnummer for dit projekts afhængigheder,
Et ny komponent oprettes med denne kommando:
$ ng generate component sidebar
… eller via den forkortede:
$ ng g c sidebar
… og “sidebar” er komponentets valgfri navn. Det skal naturligvis være et sigende navn der fortæller noget om hvad komponentets opgave er.
Den anden kolonne er næsten selvforklarende. Det er her app’ens indhold (content) bliver vist alt efter hvor i app’en brugeren befinder sig. Derfor har vi her tilføjet   som blev generet da vi tilføjede --routing parameteren ved oprettelsen af projektet.
… og udskifter indholdet med:
Bemærk at vi i stedet for den kendte “href” attribut, bruger “routerLink”.
Vores sidebar menu skal også bruge nogle ikoner. Den tekst du ser i   html tag’et, vil ikke blive vist. Det er blot navnet på det ikon vi ønsker at benytte. I dette eksempel bruger vi Google’s “Material Icons” ikonpakke, som vi importerer ved at linke til dem i index.html. Følgende linje indsættes i head-sektionen:
Nu skal vi fortælle vores router hvor de enkelte links skal føre hen. Derfor åbnes app/app-routing.module.ts:
import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; const routes: Routes = []; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) eksport class AppRoutingModule { }
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
const routes: Routes = [];
eksport class AppRoutingModule { }
Hertil skal vi importerer alle de komponenter vi vil kunne rute til…
Vi starter derfor med at tilføje følgende på linje 3:
import { UsersComponent } from './users/users.component'; import { DetailsComponent } from './details/details.component'; import { PostsComponent } from './posts/posts.component';
import { UsersComponent } from './users/users.component';
import { DetailsComponent } from './details/details.component';
import { PostsComponent } from './posts/posts.component';
Dette er kun for eksemplets skyld, da vi ikke har oprettet disse komponenter.
Nu associerer vi hvert komponent med en url. Dette gøres ved at udskifte linjen…
const routes: Routes = [];
const routes: Routes = [];
const routes: Routes = [ { path: '', component: UsersComponent }, { path: 'details/:id', component: DetailsComponent }, { path: 'posts', component: PostsComponent }, ];
const routes: Routes = [
Dermed har vi fortalt at UsersComponent er vores standard indhold når intet andet er defineret. Det er altså vores forside. For DetailsComponent ønsker vi url’en /details og har samtidig angivet at der her skal være mulighed for at medsende en værdi, nemlig et id. Og for PostsComponent skal url’en slet og ret være /posts.
Opret en liste og hent data
Nu skal vi oprette en service til visning af vores brugerliste i UsersComponent. Men lad os først oprette UsersComponent:
$ ng g c users
$ ng g c users
… og nu en service til at hente data med (data er et valgfrit navn):
$ ng generate service data
$ ng generate service data
$ ng g s data
$ ng g s data
Dette skaber ikke en ny mappe, men placerer blot service filerne under app/.
Filen data.service.ts ser således ud:
import { Injectable } from '@angular/core'; @Injectable({ providedIn: 'root' }) eksport class DataService { constructor() { } }
import { Injectable } from '@angular/core';
eksport class DataService {
En service består af kode som kan genbruges hvor som helst. Den bekymrer sig ikke om design, men leverer blot noget funktionalitet eller data.
I dette tilfælde vil vi hente brugerdata fra et api. Vi vælger i dette tilfælde at hente fra en online service der stiller eksempeldata til rådighed: jsonplaceholder.typicode.com
I linje 2 tilføjer vi:
import { HttpClient } from '@angular/common/http';
import { HttpClient } from '@angular/common/http';
… vi føjer HttpClient til constructor metoden og indsætter en ny funktion der henter brugerdata:
constructor(private http: HttpClient) { } getUsers() { return this.http.get('https://jsonplaceholder.typicode.com/users') }
constructor(private http: HttpClient) { }
Nu importerer vi HttpClient modulet i app.module.ts:
import { HttpClientModule } from '@angular/common/http';
import { HttpClientModule } from '@angular/common/http';
… og i samme fil, føjer vi den til imports:
imports: [ BrowserModule, AppRoutingModule, HttpClientModule, // <- Tilføj her ],
HttpClientModule,  // <- Tilføj her
Vores nye data service skal nu importeres til det komponent vi skal bruge det i. Vi åbner derfor user.component.ts og angiver en import linje:
import { DataService } from '../data.service';
import { DataService } from '../data.service';
Samme sted importerer vi rxjs som basalt set er den der indeholder de data vi henter:
import { Observable } from 'rxjs';
import { Observable } from 'rxjs';
… og vi føjer lidt til vores eksport class sektion:
eksport class UsersComponent implements OnInit { users$: Object; constructor(private data: DataService) { } ngOnInit() { this.data.getUsers().subscribe( data => this.users$ = data ); } }
eksport class UsersComponent implements OnInit {
constructor(private data: DataService) { }
data => this.users$ = data
Nu skal vi vise listen og det foregår i users.component.html:
Users       {{ user.name }}     {{ user.email }}    {{ user.website }}
Nu genererer vi vores details komponent:
# ng g c details
# ng g c details
… og føjer et par ekstra funktioner til app/data.service.ts nemlig getUser og getPosts:
constructor(private http: HttpClient) { } getUsers() { return this.http.get('https://jsonplaceholder.typicode.com/users') } getUser(userId) { return this.http.get('https://jsonplaceholder.typicode.com/users'+userId) } getPosts() { return this.http.get('https://jsonplaceholder.typicode.com/posts') }
constructor(private http: HttpClient) { }
Vores details komponent skal også benytte brugerdata og vi importerer derfor også vores dataservice og rxjs her. Åben details.component.ts:
import { DataService } from '../data.service'; import { Observable } from 'rxjs';
import { DataService } from '../data.service';
import { Observable } from 'rxjs';
Denne linje skal også tilføjes, og den giver mening om lidt:
import { ActivatedRoute } from '@angular/router';
import { ActivatedRoute } from '@angular/router';
… og vi føjer lidt til vores eksport class sektion:
eksport class DetailsComponent implements OnInit { user$: Object; constructor(private route: ActivatedRoute, private data: DataService) { this.route.params.subscribe( params => this.user$ = params.id ); } ngOnInit() { this.data.getUser(this.user$).subscribe( data => this.user$ = data ); } }
eksport class DetailsComponent implements OnInit {
constructor(private route: ActivatedRoute, private data: DataService) {
this.route.params.subscribe( params => this.user$ = params.id );
data => this.user$ = data
Det nye i ovenstående er linje 6. Her henviser vi med params.id til den parameter i url’en vi navngav id i  rutefilen. Og vi kan nu se at ActivatedRoute giver os adgang til den aktuelle værdi af den parameter. Navnet alene er næsten selvforklarende: Activated route = Den aktive rute, dvs. den url og det komponent der pt er aktivt og det er i dette tilfælde “details”. Du kan læse mere om ActivatedRoute her: Angular – ActivatedRoute
I filen details.component.html indsætter vi nu følgende:
{{ user$.name }}      Username:  {{ user$.username }}    Email:  {{ user$.email }}    Phone:  {{ user$.phone }}
Username:  {{ user$.username }}
Email:  {{ user$.email }}
Phone:  {{ user$.phone }}
Vi skal også vise beskeder (posts):
$ ng g c posts
$ ng g c posts
… og vores posts.component.ts:
import { Component, OnInit } from '@angular/core'; import { DataService } from '../data.service'; import { Observable } from 'rxjs'; @Component({ selector: 'app-posts', templateUrl: './posts.component.html', styleUrls: ['./posts.component.scss'] }) eksport class PostsComponent implements OnInit { posts$: Object; constructor(private data: DataService) { } ngOnInit() { this.data.getPosts().subscribe( data => this.posts$ = data ); } }
import { Component, OnInit } from '@angular/core';
import { DataService } from '../data.service';
import { Observable } from 'rxjs';
eksport class PostsComponent implements OnInit {
constructor(private data: DataService) { }
data => this.posts$ = data
Posts       {{ post.title }}   {{ post.body }}
Marker den aktuelle side i menuen
Nu kunne det være smart at markere hvilket menupunkt der pt er aktivt i vores menu (sidebar). Vi åbner derfor sidebar.component.ts:
import { Component, OnInit } from '@angular/core'; import { Router, NavigationEnd } from '@angular/router'; @Component({ selector: 'app-sidebar', templateUrl: './sidebar.compotent.html', styleUrls: ['./sidebar.component.css'] }); eksport class SidebarComponent implements OnInit { currentUrl: string; constructor(private router: Router) { router.events.subscribe((_: NavigationEnd) => this.currentUrl = _.url); } ngOnInit() {} }
import { Component, OnInit } from '@angular/core';
import { Router, NavigationEnd } from '@angular/router';
eksport class SidebarComponent implements OnInit {
constructor(private router: Router) {
router.events.subscribe((_: NavigationEnd) => this.currentUrl = _.url);
I vores constructor abonnerer vi nu på event’et NavigationEnd. Dvs. når en navigation/sideskift er slut, får vi her besked om det, og får den aktuelle url.
I sidebar.component.html redigeres de eksisterende   tags:
Dette betyder at når et link er aktivt vil css klassen ‘activated’ bliver tilføjet, således at   tagget i browseren ser således ud:
Det næste vi skal prøve er at animere html-elementer. Først installerer vi Angulars animate modul:
# npm install @angular/animations@latest --save
# npm install @angular/animations@latest --save
Modulet skal nu importeres til app.module.ts
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
… og vi føjer det samtidig til imports:
@NgModule({ ... imports: [ ... BrowserAnimationsModule ], })
import { trigger,style,transition,animate,keyframes,query,stagger } from '@angular/animations';
import { trigger,style,transition,animate,keyframes,query,stagger } from '@angular/animations';
… og i @Component sektionen:
@Component({ selector: 'app-users', templateUrl: './users.component.html', styleUrls: ['./users.component.scss'], // Tilføj dette: animations: [ trigger('listStagger', [ transition('*   *', [ query( ':enter', [ style({ opacity: 0, transform: 'translateY(-15px)' }), stagger( '50ms', animate( '550ms ease-out', style({ opacity: 1, transform: 'translateY(0px)' }) ) ) ], { optional: true } ), query(':leave', animate('50ms', style({ opacity: 0 })), { optional: true }) ]) ]) ] })
style({ opacity: 0, transform: 'translateY(-15px)' }),
style({ opacity: 1, transform: 'translateY(0px)' })
{ optional: true }
query(':leave', animate('50ms', style({ opacity: 0 })), {
I users.component.html, mangler vi nu bare at henvise til vores animation i   tag’et:
Når du er klar til at offentliggøre dit projekt skal det bygges og evt. komprimeres, dvs:
Oversæt til javascript og komprimér:
$ ng build --prod
$ ng build --prod
Hvis der er nogen uhensigtsmæssigheder i dit projekt, vil byggeprocessen fortælle om det:
ERROR in src/app/details/details.component.html(1,7): Property type ‘name’ does not exist on type ‘Object’
Her har vi glemt at pakke vores visning af en brugers information ind i en ngIf, så det gør vi lige:
I filen details.component.html indsætter vi nu følgende:
{{ user$.name }}      Username:  {{ user$.username }}    Email:  {{ user$.email }}    Phone:  {{ user$.phone }}
Username:  {{ user$.username }}
Email:  {{ user$.email }}
Phone:  {{ user$.phone }}
Kommandoen build opretter en dist mappe, hvis den ikke eksisterer, og placerer der færdige projekt heri. Bemærk forskellen mellem at bygge med eller uden --prod parameteren. Projekter fylder mange mb uden og under 1 mb med. Det er komprimeringen der gør hele forskellen.
Hvis du vil lave responsive design… dvs. en hjemmeside/app der skalerer flot på alle skærmstørrelser, er det ikke nemt at komme uden om Bootstrap. Her får du det hele forærende og en nem måde at arbejde på:
$ ng add @ng-bootstrap/schematics
$ ng add @ng-bootstrap/schematics
import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; @NgModule({ ...... imports: [ NgbModule.forRoot() ] ...... })
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
Hvis du har en ng serve -o kørende, skal du genstarte den for at få adgang til at benytte Bootstrap styles.
… og i hver eneste xx.component.ts hvor du vil benytte Boostrap fremover:
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
Jeg har altid brugt Vim som editor. Den er dejlig simpel og nem at anvende. Men jeg må også tilstå at jeg aldrig har været en haj til at bruge den, og har således ikke rigtig udnyttet alle de muligheder der gør redigering super effektivt. Det der med at huske en masse tastaturgenveje mens jeg sidder og programmerer – det du’r bare ikke for mig. Alligevel har jeg stædigt brugt Vim de sidste 10-15 år.
Men med Angular 6 føler jeg et behov for at prøve noget andet. En editor med GUI og hele pivtøjet. Så jeg har været på Google for at se hvad andre bruger. Webstorm lader til at være ret udbredt, men de er heller ikke kede af det sådan rent prismæssigt. Jeg lod mig derfor inspirere af dette svar på Stackoverflow… og slugte verdens største kamel. Jeg har installeret Visual Studio Code, som er en gratis editor fra [dunkel musik her] Microsoft!!! Men den er rent faktisk open source… og folk anbefaler den, så den er installeret, og foreløbig er jeg glad 🙂
Du kan se her, hvordan du installerer Visual Studio Code på nærmest enhver platform og distro: Running Visual Studio Code on Linux
Posted in Computer, Webudvikling Tagged angular 6
Nedbringe størrelsen af fedora-root
Angular i18n: Oversættelse til flere sprog
I gang med Angular 13 på Linux
Brug af grep kommandoen
Installer Asbru Connection Manager på Fedora
Installer DBeaver på Fedora
Node Package Manager (npm)
Linux: Afvikle en kommando som en anden bruger
MariaDB: Slå generel log til midlertidigt
Udskift nouveau driver med NVIDIA på Fedora 33 – og fortryd
Skab overblik over dine DMARC rapporter
Kategorier Vælg kategori Aftensmad Akrylmaling Bagværk Computer Dessert Fotografi Generelt Grød Hakket oksekød Hobby Hvidkål Ikke kategoriseret Internet IT Krop og sind PHP Pizza Politik Samfund Server Tips & Tricks Vegansk Webudvikling
Arkiver Vælg måned august 2022 april 2022 marts 2022 oktober 2021 maj 2021 marts 2021 februar 2021 januar 2021 december 2020 november 2020 oktober 2020 august 2020 juli 2020 juni 2020 marts 2020 januar 2020 december 2019 november 2019 oktober 2019 august 2019 juni 2019 april 2019 februar 2019 december 2018 oktober 2018 september 2018 juli 2018 juni 2018 maj 2018 april 2018 februar 2018 januar 2018 december 2017 oktober 2017 september 2017 august 2017 juli 2017 juni 2017 maj 2017 april 2017 januar 2017 december 2016 november 2016 oktober 2016 september 2016 januar 2016 december 2015 november 2015 oktober 2015 september 2015
Proudly powered by WordPress | Theme: chichi by xtianmark.