MoinMoin Logo
  • Comments
  • Immutable Page
  • Menu
    • Navigation
    • RecentChanges
    • FindPage
    • Local Site Map
    • Help
    • HelpContents
    • HelpOnMoinWikiSyntax
    • Display
    • Attachments
    • Info
    • Raw Text
    • Print View
    • Edit
    • Load
    • Save
  • Login

Navigation

  • Start
  • Sitemap

Upload page content

You can upload content for the page named below. If you change the page name, you can also upload content for another page. If the page name is empty, we derive the page name from the file name.

File to load page content from
Page name
Comment

  • Angular

Contents

  1. Angular
    1. Concepts from AngularJS
    2. MVVM
    3. Components
    4. Template
    5. Services, dependency injection
    6. Router - navigation
    7. Project structure
    8. Run angular tests with code coverage
    9. Karma jasmine show console.log()
    10. Example project
    11. Angular change detection

Angular

  • https://angular.io/guide/architecture

Angular is a platform and framework for building single-page client applications (SPA) in HTML and typescript.

The architecture of an Angular application relies on certain fundamental concepts. The basic building blocks are NgModules, which provide a compilation context for components.

Concepts from AngularJS

  • https://docs.angularjs.org/guide/concepts

    • Model - the data shown to the user in the view and with which the user interacts

    • View - what the user sees (the DOM)

    • Controller - the business logic behind views

    • Dependency Injection - Creates and wires objects and functions

MVVM

  • https://angular.io/guide/template-syntax

  • https://angular.dev/guide/templates

In Angular (MVVM)(MVC)

  • the component plays the part of the controller or viewmodel,

  • and the template represents the view.

  • The model represents the business model/domain model

Model–view–viewmodel is also referred to as model–view–binder, especially in implementations not involving the .NET platform

  • https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93viewmodel

MVVM facilitates a separation of development of the graphical user interface – be it via a markup language or GUI code – from development of the business logic or back-end logic (the data model).

The view model of MVVM is a value converter,[1] meaning the view model is responsible for exposing (converting) the data objects from the model in such a way that objects are easily managed and presented.

View Model is a conversion of data from the Model to be used by the View.

  • https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93viewmodel#Components_of_MVVM_pattern

    • Model: Model refers either to a domain model,

    • View: structure, layout, and appearance of what a user sees on the screen. It displays a representation of the model and receives the user's interaction with the view and it forwards the handling of these to the view model via the data binding.

    • View Model: abstraction of the view exposing public properties and commands. It has a binder, which automates communication between the view and its bound properties in the view model. The view model has been described as a state of the data in the model.

Components

Components define views. Components use services, which provide specific functionality not directly related to views. Service providers can be injected into components as dependencies, making your code modular, reusable, and efficient.

Each component defines a class that contains application data and logic, and is associated with an HTML template that defines a view to be displayed in a target environment.

Template

A template combines HTML with Angular markup that can modify HTML elements before they are displayed. Template directives provide program logic, and binding markup connects your application data and the DOM. There are two types of data binding: Event binding lets your app respond to user input in the target environment by updating your application data; Property binding lets you interpolate values that are computed from your application data into the HTML.

Services, dependency injection

For data or logic that isn't associated with a specific view, and that you want to share across components, you create a service class. A service class definition is immediately preceded by the @Injectable() decorator.

Router - navigation

The Angular Router NgModule provides a service that lets you define a navigation path among the different application states and view hierarchies in your app

Project structure

  • https://angular.io/guide/file-structure

  • https://angular.dev/reference/configs/file-structure

   1 # ng new command creates a workspace. 
   2 ng new <my-project>

Run angular tests with code coverage

   1 ng test --codeCoverage=true --watch=false

Karma jasmine show console.log()

In karma.conf

  • find client.jasmine.captureConsole
  • change it from false to true

Example project

   1 ng new test-ng
   2 cd test-ng/
   3 ng build
   4 ng serve
   5 ng generate component abscomponent
   6 ng generate component conccomponent

Structure without dist and node_modules

.
├── angular.json
├── browserslist
├── e2e
│   ├── protractor.conf.js
│   ├── src
│   │   ├── app.e2e-spec.ts
│   │   └── app.po.ts
│   └── tsconfig.json
├── karma.conf.js
├── package.json
├── package-lock.json
├── README.md
├── src
│   ├── app
│   │   ├── abscomponent
│   │   │   ├── abscomponent.component.css
│   │   │   ├── abscomponent.component.html
│   │   │   ├── abscomponent.component.spec.ts
│   │   │   ├── abscomponent.component.ts
│   │   │   ├── tableheader.ts
│   │   │   ├── tablerow.ts
│   │   │   └── testdata.ts
│   │   ├── app.component.css
│   │   ├── app.component.html
│   │   ├── app.component.spec.ts
│   │   ├── app.component.ts
│   │   ├── app.module.ts
│   │   └── conccomponent
│   │       ├── conccomponent.component.css
│   │       ├── conccomponent.component.html
│   │       ├── conccomponent.component.spec.ts
│   │       └── conccomponent.component.ts
│   ├── assets
│   ├── environments
│   │   ├── environment.prod.ts
│   │   └── environment.ts
│   ├── favicon.ico
│   ├── index.html
│   ├── main.ts
│   ├── polyfills.ts
│   ├── styles.css
│   └── test.ts
├── tsconfig.app.json
├── tsconfig.json
├── tsconfig.spec.json
└── tslint.json

app.component.html

Add conccomponent to app.component.html

   1 <div class="content" role="main">
   2   <app-conccomponent></app-conccomponent>

abscomponent.component.html

   1 <p>abscomponent works! {{message}}</p>
   2 
   3 <div style="height: 100px; overflow-y: scroll;margin-bottom: 25px;">
   4     <table>
   5         <tr>
   6             <th *ngFor="let h of headers">{{h.name}}</th>
   7         </tr>
   8         <tr *ngFor="let row of rows">
   9             <td *ngFor="let value of row.values">
  10                 {{value}}
  11             </td>
  12         </tr>
  13     </table>
  14 </div>

abscomponent.component.ts

   1 import { Component, OnInit, Input } from '@angular/core';
   2 import { TestData } from './testdata';
   3 import { TableHeader } from './tableheader';
   4 import { TableRow } from './tablerow';
   5 
   6 @Component({
   7   selector: 'app-abscomponent',
   8   templateUrl: './abscomponent.component.html',
   9   styleUrls: ['./abscomponent.component.css']
  10 })
  11 export abstract class AbscomponentComponent implements OnInit {
  12 
  13   @Input()
  14   message: string = "Message";
  15 
  16   items: TestData[];
  17   headers: TableHeader[];
  18   rows: TableRow[];
  19 
  20   constructor() {
  21     this.items = [];
  22     this.headers = [];
  23     this.rows = [];
  24   }
  25 
  26   ngOnInit(): void {
  27   }
  28 
  29   public configure(input: string, data: TestData[], header: TableHeader[], rows: TableRow[]): void {
  30     this.message = input;
  31     this.items = [];
  32     this.headers = [];
  33     this.rows = [];
  34 
  35     // on push detector
  36     data.forEach(element => {
  37       this.items.push(element);
  38     });
  39 
  40     header.forEach(element => {
  41       this.headers.push(element);
  42     });
  43 
  44     rows.forEach(element => {
  45       this.rows.push(element);
  46     });
  47 
  48     console.log("configure called");
  49   }
  50 }

testdata.ts

   1 export interface TestData {
   2     name: string;
   3 }

tableheader.ts

   1 export interface TableHeader {
   2     name: string;
   3 }

tablerow.ts

   1 export interface TableRow {
   2     values: string[];
   3 }

conccomponent.component.ts

   1 import { Component, OnInit } from '@angular/core';
   2 import { AbscomponentComponent } from '../abscomponent/abscomponent.component';
   3 import { TestData } from '../abscomponent/testdata';
   4 import { TableHeader } from '../abscomponent/tableheader';
   5 import { TableRow } from '../abscomponent/tablerow';
   6 
   7 @Component({
   8   selector: 'app-conccomponent',
   9   templateUrl: '../abscomponent/abscomponent.component.html', //uses base class html
  10   styleUrls: ['../abscomponent/abscomponent.component.css']  // uses base class css
  11 })
  12 export class ConccomponentComponent extends AbscomponentComponent implements OnInit {
  13 
  14   constructor() {
  15     super();
  16   }
  17 
  18   ngOnInit(): void {
  19     let itemsx: TestData[];
  20     itemsx = [];
  21     itemsx.push({ name: "concrete" });
  22     itemsx.push({ name: "concreteaaa" });
  23     itemsx.push({ name: "asd" });
  24     let headers: TableHeader[];
  25     let rows: TableRow[];
  26     headers = [];
  27     headers.push({ name: "namea" });
  28     headers.push({ name: "nameb" });
  29 
  30     rows = [];
  31     rows.push({ values: ["x1", "y1"] });
  32     rows.push({ values: ["x2", "y2"] });
  33     rows.push({ values: ["x3", "y3"] });
  34     rows.push({ values: ["x4", "y4"] });
  35     rows.push({ values: ["x5", "y5"] });
  36     rows.push({ values: ["x6", "y6"] });
  37     rows.push({ values: ["x7", "y7"] });
  38     rows.push({ values: ["x8", "y8"] });
  39     this.configure(this.message + " extended !", itemsx, headers, rows);
  40   }
  41 
  42 }

Angular change detection

  • https://www.mokkapps.de/blog/the-last-guide-for-angular-change-detection-you-will-ever-need/

  • https://angular.io/api/core/ChangeDetectorRef

  • https://angular.dev/api/core/ChangeDetectorRef

In short, the framework will trigger a change detection if one of the following events occurs:

  • any browser event (click, keyup, etc.)
  • setInterval() and setTimeout()
  • HTTP requests via XMLHttpRequest

   1 constructor(private ref: ChangeDetectorRef) {
   2 //...
   3 }
   4 this.ref.detectChanges(); // trigger detection change
   5 
  • MoinMoin Powered
  • Python Powered
  • GPL licensed
  • Valid HTML 4.01