顯示具有 javascript 標籤的文章。 顯示所有文章
顯示具有 javascript 標籤的文章。 顯示所有文章

Angular - Built-in directives

ngIf
true => Host div will be included in the HTML elements
false => Host div will be excluded in the HTML elements
<div *ngIf="needShow(4)" class="bg-info p-2 mt-1"> Check need to show if pass 4 </div>
<div *ngIf="doNotShow()" class="bg-info p-2 mt-1"> Expect do not show this element </div>

ngSwitch
Same, only matched element will be included in the HTML elements.
However the ngSwitch host element will always be included in HTML element.
<div class="bg-info p-2 mt-1" [ngSwitch]="howManyPeople()"> 
    <span *ngSwitchCase="2">There are two people</span> 
    <span *ngSwitchCase="5">There are five people</span> 
    <span *ngSwitchDefault>This is the default</span> 
</div>

Need double quote when comparing string
<div class="bg-info p-2 mt-1" [ngSwitch]="whatIsYourName()">
    <span *ngSwitchCase="'Anderson'">I know you!!</span>
    <span *ngSwitchCase="'QQ'">Hi, nice to meet you</span>
    <span *ngSwitchDefault>Hello?</span>
</div>

ngFor
repeats a section of content for each object in an array, providing the template equivalent of a foreach loop.
Template variables: index (zero based number), odd (boolean), even (boolean), first (boolean), last (boolean)
<tr *ngFor="let item of getProducts(); let i = index; let odd = odd; let even = even"> 
    <td>{{item.name}}</td> 
    <td>{{item.category}}</td>
    <td>{{item.price}}</td> 
</tr>

由於 ngFor 需要 iterate data, 當 data source 改變的時候, ngFor 需要重新跑一次 data source 會讓效能變差.
為了提升效能, 可以在 component 訂一個 method, 例如 getKey (注意 signature 第一個參數是 index, 第二個參數是 object), 然後在 ngFor 裡面定義 trackBy:getKey, 如此就能讓 ngFor 了解雖然是從 data source 拿到新的物件, 但其實是同一筆資料
  1. define getKey method
import { ApplicationRef, Component } 
from "@angular/core"; 
import { Model } from "./repository.model"; 
import { Product } from "./product.model"; 
@Component({ 
    selector: "app", 
    templateUrl: "template.html" 
})
export class ProductComponent { 
model: Model = new Model(); 
    // ...constructor and methods omitted for brevity... 

    getKey(index: number, product: Product) { 
        return product.id; 
    } 
}
  1. 定義 trackBy:getKey
<tr *ngFor="let item of getProducts();let i = index;let odd = odd;let even = even;trackBy:getKey">
    <td>{{item.name}}</td>
    <td>{{item.category}}</td>
    <td>{{item.price}}</td>
</tr>

ngTemplateOutlet
Used to repeat a block of content in a specified location
  1. Define a template and the content
<ng-template #myTemplate> 
    <div>Hello</dic>
</ng-template>

  1. Output the template
<ng-template [ngTemplateOutlet]="myTemplate"></ng-template>
<div>KKKKK</div>
<ng-template [ngTemplateOutlet]="myTemplate"></ng-template>

Provide Context Data Binding
  1. Define template with context. We defined "text" variable in template, and the value will be the expression result of "title"
    (Use let- to define a variable)
<ng-template #myTemplate let-text="title"> 
    <h4 class="p-2 bg-success text-white">{{text}}</h4> 
</ng-template>

  1. Use the defined template and provide data for binding
<ng-template [ngTemplateOutlet]="myTemplate" [ngTemplateOutletContext]="{title: 'Header'}"> </ng-template>


Keep in mind
  1. Expressions need to be idempontent
  2. Can NOT access objects defined outside of the template's component, and in particular, templates can't access the global namespace.
  3. Global namespace must be provided by component, acting as on behalf of the template
import { ApplicationRef, Component }
from "@angular/core";
import { Model } from "./repository.model";
import { Product } from "./product.model";
@Component({
    selector: "app",
    templateUrl: "template.html"
})
export class ProductComponent {
model: Model = new Model();
    // ...constructor and methods omitted for brevity...

    getNumber(): number {
        return Math.floow(1); // The Math can't be accessed by template
    }

    getKey(index: number, product: Product) {
        return product.id;
    }
}


express.js - body-parser - specific uri

 

Commit

code
var express = require('express');
var bodyParser = require('body-parser')
var app = express()
    .use( '/test', bodyParser() ).use(function (req, res) {
        console.log("body", req.body)
        console.log("foo", req.body.foo)
        res.send(req.body)
    })
    .listen(3000);

execute
$ node app.js

curl
$ curl -s  http://127.0.0.1:3000/test/  -H "content-type: application/json" -d   "{\"foo\":123}"
{"foo":123}

express.js - express.static - index file

  • Commit


  • use express.static
var express = require('express');  
var app = express()  
            .use(  express.static(__dirname + '/public')  )  
            .listen(3000);


inquirer - mark todo item done

By ‘checkbox’ type can choose items

Commit

Code
import * as inquirer from "inquirer"

// Object.values(Commands) will become [List, Quit, 1, 2] without specifying string value
enum Commands {
    Add = "Add",
    Done = "Done",
    Quit = "Quit"
}

let todo: Array<Task> = []

promptList()

class Task {
    done: boolean = false;
    constructor(public name:string) {
    }
    markDone() {
        this.done = true
    }
    toString = ():string => {
        return this.name + "=>" + (this.done ? "done" : "not done")
    }
}

function listTodo() {
    todo.forEach(item => {
        console.log(`${item}`)
    })
}

function promptDone() {
    inquirer.prompt({
        type: "checkbox",
        name: "check",
        message: "Mark done:",
        choices: todo.map(item => ({
            name: item.name,
            value: item.name,
            checked: item.done
        }))
    }).then(answers => {
        console.log(answers)
        let checkedItems = answers['check'] as string[]
        if (answers['check'] != "") {
            todo.forEach(item => item.done = false)
            todo.forEach(item => {
                checkedItems.forEach(checkedItem => {
                    if (item.name == checkedItem) {
                        item.done = true
                    }
                })
            })
        }
        promptList();
    })
}

function promptAdd() {
    inquirer.prompt({
        type: "input",
        name: "add",
        message: "Input TODO:",
    }).then(answers => {
        if (answers['add'] != "") {
            todo.push(new Task(answers['add']))
        }
        promptList();
    })
}

function promptList() {
    console.clear();
    listTodo();
    inquirer.prompt({
        type: "list",
        name: "command",
        message: "Choose option",
        choices: Object.values(Commands)
    }).then(answers => {
        switch (answers["command"]) {
            case Commands.Add:
                promptAdd();
                break;
            case Commands.Done:
                promptDone();
                break;
            case Commands.Quit:
                console.log("Select Quit")
                break;
            default:
                console.log("Missing " + answers["command"])
        }
    })
}

Inquirer - add item to list

Use "input" type in inquirer can support input information

Commit

Code
import * as inquirer from "inquirer"

// Object.values(Commands) will become [List, Quit, 1, 2] without specifying string value
enum Commands {
    AddTodo = "AddTodo",
    Quit = "Quit"
}

promptList()

var todo: Array<string> = []

function listTodo() {
    console.log(todo)
}

function promptAdd() {
    inquirer.prompt({
        type: "input",
        name: "add",
        message: "Input TODO:",
    }).then(answers => {
        if (answers['add'] != "") {
            todo.push(answers['add'])
        }
        promptList();
    })
}

function promptList() {
    console.clear();
    listTodo();
    inquirer.prompt({
        type: "list",
        name: "command",
        message: "Choose option",
        choices: Object.values(Commands)
    }).then(answers => {
        switch (answers["command"]) {
            case Commands.AddTodo:
                promptAdd();
                break;
            case Commands.Quit:
                console.log("Select Quit")
                break;
            default:
                console.log("Missing " + answers["command"])
        }
    })
}




inquirer - simple list and quit command

Git Repository

Install libraries
npm install inquirer
npm install typescript

List and Quit commands
import * as inquirer from "inquirer"


// Object.values(Commands) will become [List, Quit, 1, 2] without specifying string value
enum Commands {
    List = "List",
    Quit = "Quit"
}


inquirer.prompt({
    type: "list",
    name: "command",
    message: "Choose option",
    choices: Object.values(Commands)
}).then(answers => {
    switch (answers["command"]) {
        case Commands.List:
            console.log("Select List")
            break;
        case Commands.Quit:
            console.log("Select Quit")
            break;
        default:
            console.log("Missing " + answers["command"])
    }
})

redux - typescript - change index.js to support typescript

Git Commit

  • Install typescript
npm install --save-dev typescript
  • New Helloworld.ts
export class Helloworld {
    public name: String;

    public constructor(name:String) {
        this.name = name;
    }

    public greeting(): void {
        console.log(`Helloworld! ${this.name}`);
    }
}
  • New TodoItem.ts
export class TodoItem {
    public constructor(public id:String, public task:String, public done:boolean) {
    }

    public printDetail():void {
        console.log(`${this.id} / ${this.task} / ${this.done}`);
    }
}
  • New TodoItemCollection.ts
import {TodoItem} from "./TodoItem";

export class TodoItemCollection {
    constructor(public name:String, public todoItems: TodoItem[]) {
    }

    public addItem(item: TodoItem): number {
        return this.todoItems.push(item);
    }

    public getItemById(id:String): TodoItem | undefined {
        return this.todoItems.find(item => item.id === id);
    }

    public markDone(id:String) {
        const item = this.getItemById(id)
        if (item) {
            item.done = true
        }
    }
}
  • Rename index.js to index.tsx
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import {createStore, applyMiddleware} from 'redux'
import { Provider } from 'react-redux'
import reducers from './reducers'
import thunk from "redux-thunk";
import {Helloworld} from './ts/Helloworld'
import {TodoItemCollection} from "./ts/TodoItemCollection";
import {TodoItem} from "./ts/TodoItem";

const store = createStore(reducers, applyMiddleware(thunk));

ReactDOM.render(
      <Provider store={store} >
          <App />
      </Provider>,
  document.getElementById('root')
);

const h = new Helloworld("KKK");
h.greeting();

const todos = new TodoItemCollection("name1", [
    new TodoItem("id1", "task1", false),
    new TodoItem("id2", "task2", false),
    new TodoItem("id3", "task3", false),
]);
todos.addItem(new TodoItem("id4", "task4", false));
console.log(todos);
todos.markDone("id2");
console.log(todos.getItemById("id2"));
  • Check typescript works


Lessons Learned While Benchmarking vLLM with GPU

Recently, I benchmarked vLLM on a GPU to better understand how much throughput can realistically be expected in an LLM serving setup. One ...