Hello
Github blog : https://github.com/lucifiel0121/blog Medium : https://medium.com/@Ashe_Li
A tech blog about Front-end
Hello
Github blog : https://github.com/lucifiel0121/blog Medium : https://medium.com/@Ashe_Li
以下為有答案的練習紀錄,原題目網站於上方
The Array is Javascript's only collection type. Arrays are everywhere. We're going to add the five functions to the Array type, and in the process make it much more powerful and useful. As a matter of fact, Array already has the map, filter, and reduce functions! However we're going to reimplement these functions as a learning exercise.
This section will follow a pattern. First we'll solve problems the way you probably learned in school, or on your own by reading other people's code. In other words, we'll transform collections into new collections using loops and statements. Then we'll implement one of the five functions, and then use it to solve the same problem again without the loop. Once we've learned the five functions, you'll learn how to combine them to solve complex problems with very little code. The first two exercises have been completed in advance, but please look them over carefully!
Nearly every time we flatten a tree we chain map() and concatAll(). Sometimes, if we're dealing with a tree several levels deep, we'll repeat this combination many times in our code. To save on typing, let's create a concatMap function that's just a map operation, followed by a concatAll.
按照 Exercise 12 的經驗,Map()、concatAll() 時常是一組的,工程師不喜歡做重複的工作,所以就有 concatMap():
Let's repeat the exercise we just performed. However this time we'll simplify the code by replacing the map().concatAll() calls with concatMap().
(
)
是語法提示[color=#907bf7]Sometimes we need to perform an operation on more than one item in the array at the same time. For example, let's say we need to find the largest integer in an array. We can't use a filter() operation, because it only examines one item at a time. To find the largest integer we need to compare items in the array to each other.
有時候需要同一時間計算 不只一個
的運算,比如說要從一個陣列中尋找最大的整數,這時候就不能用 filter() 運算子,因為它一次只能檢驗一個
值。為了尋找最大的整數,我們需要相互比較陣列裡的元素。
[color=#907bf7]One approach could be to select an item in the array as the assumed largest number (perhaps the first item), and then compare that value to every other item in the array. Each time we come across a number that was larger than our assumed largest number, we'd replace it with the larger value, and continue the process until the entire array was traversed.
有一種方法,
選擇陣列中的一項,作為假設的最大數字(可能是第一項),然後將該值與陣列中的其他項進行比較,當我們遇到一個大於我們假設的最大數字時,我們用最大的值替換它,並繼續該過程,直到遍歷整個陣列。
[color=#907bf7]If we replaced the specific size comparison with a closure, we could write a function that handled the array traversal process for us. At each step our function would apply the closure to the last value and the current value and use the result as the last value the next time. Finally we'd be left with only one value. This process is known as reducing because we reduce many values to a single value.
如果我們用閉包(closure)替換特定的大小的比較,可以為我們編寫一個處理陣列遍歷過程的函式。
每一步,我們的函式都會將閉包應用於最後一個值和當前值,並在下次使用結果作為最後一個值。最後,我們只留下一個值。此過程稱為縮減,因為我們將許多值減少為單個值。
[1,2,3].reduce( (accumlator,currentValue) => accumlator + currentValue, initialValue)
// console : [6]
// 若沒有給 initialValue ,則用 array[0] 作為 initialValue
// console :
// acc curr
// 1 2 (= 3)
// 3 3
// 6
// 但是在 Jafar Husain 的教學裡 ,他把 reduce 的回傳複寫加上陣列
// console: [6]
原生 Array.prototype.reduce() 回傳值 :
若是原生 Array.prototype.reduce(), 一個空陣列,回傳 TypeError
// reduce() without initialValue
[ { x: 22 }, { x: 42 } ].reduce( maxCallback ); // 42
[ { x: 22 } ].reduce( maxCallback ); // { x: 22 }
[ ].reduce( maxCallback ); // TypeError
上述原因,會讓使用受限,因為
一個
item :
至少
要有 兩項
才能作用用常用的 forEach 示範一個問題。
理解 how it work 之後,這邊幫你實作好了,關鍵return [accumulatedValue];
放在 Array 是刻意為之。
Let's use our new reduce function to isolate the largest value in an array of ratings.
三元運算子:
function() {
var ratings = [2,3,1,4,5];
return ratings.reduce( (acc,curr) => acc > curr ? acc : curr )
}
Let's try combining reduce() with map() to reduce multiple boxart objects to a single value: the url of the largest box art.
Sometimes when we reduce an array, we want the reduced value to be a different type than the items stored in the array. Let's say we have an array of videos and we want to reduce them to a single map where the key is the video id and the value is the video's title.
{
"id": 65432445,
"title": "The Chamber"
}
目標 ↓
[
{
"65432445": "The Chamber"
}
]
不過不建議
。
85行這種方式,會複寫掉原本的值,所以console每次多一筆都是把原來值複寫,稱作可變(mutability)。
如果習慣用這種方式撰寫,很容易在程式的另一個地方(B.accumulatedMap),不小心改變原先這筆資料(A.accumulatedMap)。
如此造成資料錯誤,且無法追蹤(不知道是誰最開始改變的),
這種撰寫風格會使程式:
所以先前的教學強調,每一個屬性都是 return new array
當然,可以自己創一個新的array,讓值賦予新的array (84行)
但是這種調用方式,成本很大,建議使用JS原型鍊的方式調用 Object.creat
person = { name : "Ashe" }
// person 是一個原型物件 (實體)
anotherPerson = Object.create(person);
// anotherPerson 是一個指向 person物件 的參考物件 (沒有實體)
anotherPerson
// console : {}
JSON.stringify( anotherPerson )
// console: "{}"
// 證明沒有實體
anotherPerson.name
// console : "Ashe"
// 複製一個指向指向 person.name = "Ashe" 的 參考 (copy ref)
如果再變更 person 為person = { name : "Ashe Li" }
,
因為 person.name 已經被複製,所以不會改到 anotherPerson.name
anotherPerson 依然沒有值。
更詳細可以找其他資料~
用 Object.create() 可以降低成本(memory),用比較好的方法達到成果。
(改為 var clone 是為了可以分辨)
以上這種方式(風格),稱為
以下為有答案的練習紀錄,原題目網站於上方
The Array is Javascript's only collection type. Arrays are everywhere. We're going to add the five functions to the Array type, and in the process make it much more powerful and useful. As a matter of fact, Array already has the map, filter, and reduce functions! However we're going to reimplement these functions as a learning exercise.
This section will follow a pattern. First we'll solve problems the way you probably learned in school, or on your own by reading other people's code. In other words, we'll transform collections into new collections using loops and statements. Then we'll implement one of the five functions, and then use it to solve the same problem again without the loop. Once we've learned the five functions, you'll learn how to combine them to solve complex problems with very little code. The first two exercises have been completed in advance, but please look them over carefully!
簡單介紹使用,連答案都不用寫,不過還是練習一下 forEach iterable的特性
Let's repeat the previous exercise using the forEach function.
結果需要練習 forEach , 當做對答案 ...
也是有填寫好了,不懂原理可以去找一下資料
For each video, add a projected {id, title} pair to the videoAndTitlePairs array.
用 forEach 過濾資料,開始有接API的感覺了
array.map() 的版本:
To make projections easier, let's add a map() function to the Array type. Map accepts the projection function to be applied to each item in the source array, and returns the projected array.
在原有的Array type上, 增加 map 方法
練習了解原生 map 作法的練習
Let's repeat the exercise of collecting {id, title} pairs for each video in the newReleases array, but this time we'll use our map function.
前面(Exercise-3)不小心把這題寫掉了,pass
Use forEach() to loop through the videos in the newReleases array and, if a video has a rating of 5.0, add it to the videos array.
過濾掉 rating,只取剛好等於 5.0 的 data
To make filtering easier, let's add a filter() function to the Array type. The filter() function accepts a predicate. A predicate is a function that accepts an item in the array, and returns a boolean indicating whether the item should be retained in the new array.
predicateFunction 用於測試條件是否通過,所以只會有 True or False
True : 通過條件,放入回傳的results results.push(itemInArray)
Exercise 6 換種語法的練習
第一層 forEach 取 movieLists.videos
,即過濾 movieLists.name 的資料。
第二層 forEach 取值 videos.id
,並 push 到需要回傳的 Array。
Let's add a concatAll() function to the Array type. The concatAll() function iterates over each sub-array in the array and collects the results in a new, flat array. Notice that the concatAll() function expects each item in the array to be another array.
Hint: use two nested calls to map() and one call to concatAll().
注意 concatAll()的對象是 Array of Array,所以要最後執行。
HTML5DevConf Jafar Husain, Netflix: Asyncronous JavaScript at Netflix
這篇的系列,主要來自 Jafar Husain ,
以及他在 pluralsight 開立的課程: asynchronous-javascript-rxjs-observables
Design Patterns book: Design Patterns: Elements of Reusable Object-Oriented Software: 簡單來說就是常見問題的標準解決方案
Jafar Husain 認為,有一個很重要的 design patterns relationships 被遺漏 : Iterator , Observer
" There is no line to connected ( for Iterator and Observer ). "
var iterator = getNumbers();
console.log( iterator.next() );
// console: { value: 1, done : false }
console.log( iterator.next() );
// console: { value: 2, done : false }
console.log( iterator.next() );
// console: { value: 3, done : false }
console.log( iterator.next() );
// console: { done : true }
" done "
.document.addEventListener(
"mousemove",
function next(e){
console.log(e)
}
)
" done "
, it's Infinity output ( likes Mousemove event )兩個 Patterns 的作用是一樣的,只是觀察的角度不同
Design Patterns: Iterator ( eg. Array.prototype.forEach()
) :
由 consumer 主動控制
要不要取資料 ( eg. onNext()才會取資料 ),
而且可以完成 ( done )。
Design Patterns: Observer( eg.DOM Event
) :
producer 會一直丟資料 ( eg. Mousemove event),
consumer 不能控制
,所以也不能告知 producer done
。
memory leak
. //ES 5
function(x) { return x + 1; }
function(x, y) { return x + y; }
//ES 6
x => x + 1;
(x, y) => x + y;
只要會 arrow function , 因為不想打太多 code
[1,2,3].forEach( x=> console.log(x) )
// 1
// 2
// 3
for i=1;i++;i<10
) [1,2,3].map( x=> x+1 )
// 2
// 3
// 4
[1,2,3].filter( x=> x>1 )
// [2,3]
注意: concatAll() 不是原生 js
Array.prototype.concatAll = function() {
var results = [];
this.forEach(function(subArray) {
subArray.forEach( function(item){
results.push(item);
});
});
return results;
};
注意:
若多維Array存在有空集合,concatAll後的空集合會消失。 [ [1],[2,3],[],[4] ].concatAll()
// [1, 2, 3, 4]
Observable === Collections + Time
Rx => ReactiveX => Reactive Extensions
var mouseMove = Observable.fromEvent(element,"mousemove") ;
特色 :
基本上可以想像和 Promise 類似,但是由其他兩點特色 :
Lazy : 如果創建的Observable,沒有被 subscribed 不會執行
Cancellable: 如果有大資料的loading/Request,使用者離開頁面,可以終止Http request
collection of callbacks 動作如下 :
額外的資訊 :
DOM removeEventListener
類似,但通常不會用到,..1....2...
...表示時間的流逝
先後順序(order)
不會改變儘管observable會一直丟蛋糕,但concatAll()唯一關注的是,確保下一個收到切片蛋糕的人都是按照順序
的,不會有人插隊。
{...4}
即停止removeEventListener()
),只關注何時需要設定此停止條件onError
則 此策略會停止,整個observable回傳 onError
Cancel
Button不考慮 order
first in first out
沒有暫存queue(佇列)
動畫 : https://reactive.how/merge
所有資料
,如果接受到有新的observable就把之前接受的取消subscript,直接接收最新的1. Race Conditions
2. Memory Leaks
3. Complex State Machines
4. Uncaught Async Errors
2 Actions
: A、B ,
A. 要求(request)播放電影,需要先確認 authentication id
B. 加載初始化 (initialized)
Race Conditions
狀態 State
狀態 State
轉移
,所以需要 追蹤
,Error handler
DOM : 關注 物件本身 (someSelector) 的 資料流動,collection items(may be memory leak)
observables :關注 整個系統 的 資料流動,streaming (don't collection items)
document.querySelector('someSelector').addEventListener('event',callback)
// callback(); do something
document.querySelector('someSelector').removeEventListener('event',callback)
const scroll = Rx.Observable.fromEvent(someSelector, 'event');
event.map( event => do something ... )
.subscribe()
以下為有答案的練習紀錄,原題目網站於上方
The Array is Javascript's only collection type. Arrays are everywhere. We're going to add the five functions to the Array type, and in the process make it much more powerful and useful. As a matter of fact, Array already has the map, filter, and reduce functions! However we're going to reimplement these functions as a learning exercise.
This section will follow a pattern. First we'll solve problems the way you probably learned in school, or on your own by reading other people's code. In other words, we'll transform collections into new collections using loops and statements. Then we'll implement one of the five functions, and then use it to solve the same problem again without the loop. Once we've learned the five functions, you'll learn how to combine them to solve complex problems with very little code. The first two exercises have been completed in advance, but please look them over carefully!
This is a variation of the problem we solved earlier, where we retrieved the url of the boxart with a width of 150px. This time we'll use reduce() instead of filter() to retrieve the smallest box art in the boxarts array.
concatMap()
+ 一個映射預期結果(result)的map()reduce()
,因為處理 兩個輸入
somethings.concatMap( something => something.other.
concatMap( other => other.reduce( whatever... ).
map( result =>
({
id: result.id,
value : result.value
})
)
)
Sometimes we need to combine two arrays by progressively taking an item from each and combining the pair. If you visualize a zipper, where each side is an array, and each tooth is an item, you'll have a good idea of how the zip operation works.
Use a for loop to traverse the videos and bookmarks array at the same time. For each video and bookmark pair, create a {videoId, bookmarkId} pair and add it to the videoIdAndBookmarkIdPairs array.
看起來很像兩種輸入版本的map(),不過要注意,只取兩個輸入的最小 index size
可以直接用兩層 map() 把值取出來,但通常 兩層 map() 會用於考慮
此時不考慮,因為是可以同時取出,所以處理兩個輸入
最好的方法還是使用 zip() :
movieLists.concatMap( movieList => movieList.videos.concatMap( video =>
// var samllestBoxArt = video.boxarts.reduce( ( acc , curr ) => ( acc.width * acc.height < curr.width * curr.height ) ? acc : curr );
// var middleInterestingMoments = video.interestingMoments.filter( interestingMoment => interestingMoment.type === "Middle" );
Array.zip(
video.boxarts.reduce( ( acc , curr ) => ( acc.width * acc.height < curr.width * curr.height ) ? acc : curr ) ,
video.interestingMoments.filter( interestingMoment => interestingMoment.type === "Middle" ),
( boxart, interestingMoment ) =>
({
id: video.id,
title: video.title ,
time: interestingMoment.time ,
url: boxart.url
})
)
)
)
movieLists.concatMap( movieList => movieList.videos.concatMap( video => {
var samllestBoxArt = video.boxarts.reduce( ( acc , curr ) => ( acc.width * acc.height < curr.width * curr.height ) ? acc : curr );
var middleInterestingMoments = video.interestingMoments.filter( interestingMoment => interestingMoment.type === "Middle" );
return Array.zip(
samllestBoxArt ,
middleInterestingMoments,
( boxart, interestingMoment ) =>
({
id: video.id,
title: video.title ,
time: interestingMoment.time ,
url: boxart.url
})
)
})
)
BOSS 弱點
【特定技術】需使用 JS for 迴圈技巧,裡頭數字不能直接寫在 HTML 上,需使用 JS 印出。
需使用 HTML、CSS、JS 技術
介面需與設計稿一致
下載資源
UI 線上設計稿
解題:
https://angular-f2e.stackblitz.io/
【特定技術】
改寫純樣板為可輸入變數動態產生
思考文字過多時的解決方案 (100x100乘法表內)
Code 可以 fork 回去玩玩看:
https://stackblitz.com/edit/angular-f2e
Demo
標籤,代表時間夠可以Demo。*預計 Demo 時間 40mins *
請對照 hackmd 一同閱讀 : https://hackmd.io/3uNcseF9TfeiEa0q-VDQXQ
reference 影片 ( 2Hr ) : Angular-TW-forum : VSCode 基本介紹
Demo 方便,調整顯示大小 : ctrl +/-
Demo
繁體中文:先抓繁中套件 -> F1 -> Configure Display Language -> "locale":"zh-tw"
-> 「手動」重開。
Theme 變更 : preview
demo
icon 變更: 套件 seti-icons -> F1 -> File icon theme
設定 -> 開啟 settings json -> 直接複製 別人(保哥)的設定亦可。
demo
:
:<行數>
可蒐codeemmet: 類似 code snippets ,可以快速撰寫程式碼,亦可設定要使用的檔案格式、展開方式
排版格式化工具 prettier :alt + shift + f , 針對 import : alt + shift + o
格式化的參數可以調整。
快按鍵
### 多重游標操作 - 參照 hackmd
### 內容異動 - 參照 hackmd
建議先在自己 repo or 練習用 repo 嘗試
大綱
gitignore
有套件可以快速解決Git Kistory
GitLens
1.28.1 改版新增參數 Rebase instead of merge ,
( source tree pull 第4個 )
Always rebase when running Sync :
The git.rebaseWhenSync setting will let you configure the Sync command to always use rebase instead of merge when running.
建議先看過影片介紹,(約一篇文章的長度)再閱讀文章,避免有些觀念誤會(因為文章是教材的概念撰寫的)
reference: Angular-TW-fourm : [S02E02][新手村] Typescript 101
```
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"type": "typescript",
"tsconfig": "tsconfig.json",
"option": "watch",
"problemMatcher": [
"$tsc-watch"
]
}
]
}
```
然後輸入 `$ tsc -watch`
![](https://i.imgur.com/Mb7jpRZ.png)
從圖可以得知,錯誤會直接報錯,但不會讓JS無法編譯。
--strictNullChecks
: 排除 null、undefinedinterface Square {
kind: "square";
size: number;
}
interface Rectangle {
kind: "rectangle";
width: number;
height: number;
}
interface Circle {
kind: "circle";
radius: number;
}
type Shape = Square | Rectangle | Circle;
// 三種各自獨立的 interface 裡面都有 kind (property),在建立一個額外的 type Shape 形成聯集
function area(s: Shape) {
// In the following switch statement, the type of s is narrowed in each case clause
// according to the value of the discriminant property, thus allowing the other properties
// of that variant to be accessed without a type assertion.
switch (s.kind) {
case "square": return s.size * s.size;
//只會取 square interface 中的物件 (這邊只有size)
case "rectangle": return s.width * s.height;
//只會取 rectangle interface 中的物件 (這邊有width, height)
case "circle": return Math.PI * s.radius * s.radius;
//只會取 circle interface 中的物件 (這邊只有radius)
}
}
class Hero {
constructor(params: any) {
Object.assign(this,params)
}
name: string;
state: string;
action(){}
}
const hero = new Hero({ name:'Ashe', state:'active'
// 可以 hero.action
const heroB: Hero = <Hero>{ name:'Ashe',state:'active' };
// 不可以 heroB.action ,會報錯
總結
interface AType{ }
interface BType{ }
type singleType = AType;
type unionType = AType | BType;
type IntersectionType = AType & BType;
type strinType = 'UP' | 'DOWN';
Q : type 和 interface 有甚麼差異?
- A: 兩者都是型別,但interface可以擴充(extends)
reference [S05E01][RxJS系列] JS Array 基本介紹
主要介紹及 習慣 ,如何透過文件找答案。
如果下列關鍵字全部都很熟系,這邊可以跳過。
MDN-Array links
建立 Array 的方法
var a1 = [1,2,3];
var a2 = new Array(1,2,3);
a1 // (3) [1,2,3]
a2 // (3) [1,2,3]
empty : a2 = new Array(3)
a2 // (3) [empty × 3]
console.log(a2.length) // 3
... 詳細可以看影片,這邊只是列舉部分告知...真的從基礎開始。
迭代陣列 (forEach)
Array特性:屬於object,所以可以用object method:
object.entries(a1),
object.keys(a1),
object.values(a1)
... etc
Array基本操作方法:
--
splice():基本功能 新增/刪除/插入(移除數量=0時)/替換/複製
splice 不是 pure function (執行回傳結果會不一樣)
slice 是 pure function (執行回傳結果都一樣)
Array 複製:
清除 Array 的方法 :
var fruits = [1,2,3,4] ; // (4) [1, 2, 3, 4]
fruits.length = 0 // 0
fruits = [] // 0
Array.from() : 可以把 Notelist 轉成 Array,進行 map / filter 等 array 操作
Array.concat() : 合併
Array.entries() : ie 不支援
條件測試
every()、some()、includes()
a1 = [2,4,6,8]
// (4) [2, 4, 6, 8]
a1.every( x => x < 10)
// true
a1.every( x => x < 5)
// false
Array.some() : 判斷傳入條件,是不是'其中有一'符合。只回傳 T / F
Array.includes() : 只回傳 T / F
find( )、findIndex()
a1 = [ {name:'keven'},{ name:'John' } ]
// (2) [{…}, {…}]
var user = a1.find( x=> x.name === 'John' )
user
// {name: "John"}
a1 = [ {name:'keven'},{ name:'John' } ]
// (2) [{…}, {…}]
var user = a1.findIndex( x=> x.name === 'John' )
user
// 1
a1[user]
// {name: "John"}
a1.splice(user,1)
a1
// 0:name: "keven" ,length: 1
Array.fill( ) : 填值
Array.filter( ) : 過濾
Array.join() : Array轉文字(String)
Array.map() : 轉型別,回傳新Array
forEach + 新Array 可以達到等效
Array.reduce() : 分批次計算 eg.
const array1 = [1,2,3,4]
array1.reduce( (lastValue,currentValue)=>{
console.log(lastValue,currentValue);
return lastValue+currentValue;
},0);
console :
0 1
1 2
3 3
6 4
10
Array.reverse() : 改變原本的 Array
Array.sort() : ASCII 順序或是自訂 function 排序
Array.toString()
這個心得筆記是以線上讀書會的 Angular 影片為主,摘要出一些 key words。
作者Keven也有寫過config檔案設定文章
文件有更新 CLI 7.0
注意自己本地版本與文件是否一致
Angular 7 全新功能探索 (Angular Taiwan 2018)
github docs folder : https://github.com/angular/angular-cli/tree/master/docs/documentation
wiki好讀版 : https://github.com/angular/angular-cli/wiki
node -v
、 npm -v
、 code -v
--> vscodenpm install -g @angular/cli
ng --help ,或是 ng [指令] --help 印出參數設定
ng new
(ng new --help ) : 執行時包含執行 npm install
,可以透過設定改寫成執行 yarn install
指令範例 :
ng new [projectName] --style=sass
: 可以直接寫 sass style
app.component.ts
,不額外產生另一個檔案app
- root >重點部分用標題 h3 (###)。
ng serve : 編譯後啟動 local server (port : 4200) ,參數主要是對 Web server 做設定
open:跑完直接開啟瀏覽器
可以指定,如 --port 8080
ng build : build重複執行,會把之前build的檔案覆蓋掉。
底層實作為webpack,調教參數見文檔 -stats-json
說明
ng build --prod
: 檔案輸出為 檔名有hash,目的是為了catch更新可以透過每次build不同名稱可以重新抓到新頁面deploy-url: 靜態 css,js 放在 cdn 時 ,檔案會指向 url
i18n:多國語系
extract-css:build時獨立成單個 css
ng generate [ Available Schematics ] -- Alias:ng g [ name ] : 自動產生 code & 註冊 module .
spec 可以不產生
ng new --skip-tests
"schematics": {
// comppnent 不要產生 spec , 影片 42:40s
"@schematics/angular:component": {
"spec":false
},
}
app.module.ts
*註 進階內容:可以自定義寫 CLI 產生的 template :開發出自己的 Schematics 套件
( 進階內容 - taiking in Angular conf
)
CN-Angular-Docs links : https://angular.cn/guide/quickstart#project-file-review
package.json :dependencies vs devDependencies : 開發「套件」才需要用到devDependencies,預設安裝dependencies套件區塊
版本號有規範,不贅述
"$schema" :定義 json位置,檢查 json格式
newProjectRoot :新版 cli 可以支援同目錄下,多個專案架構,所以需要依賴此設定
ng run [project-name]:[指令] -->
ng run demo:build
Beginner Friendly : GUI
試用後,還是要查文件找參數說明,不會比下指令快,
但是安裝相依套件可以不用另外找文件,可以考慮搭配使用。
.img- from twitter 10/10 : First Stable Release of Angular Console
Vue 3.0 CLI 有整合類似功能 : vue ui
reference : udemy
angular-TW-forum
F1
Ctrl + ‵
[
會自動補上 eg. [12]
ctrl + .
- alt + o : 同 comopnent 切換 .html/.ts
[
快速完成: [ 值 ]
Ctrl+Space
呼叫IntelliSenseDirective
.css[___ngcontent-c2]
推薦 SoC-關注點分離 ( html template 不要寫邏輯。邏輯統一寫在 ts )
display var 顯示變數: {{ name }}
property binding : <input type="text" [value]="name" [attr.id]="name" />
[attr.date-attr]='binding'
event binding : <botton (click)="show()"> alert </botton>
two-way binfing (語法糖): <input type="text" [(ngModel)]="name" />
<input type="text" [(ngModel)]="name" />
<input type="text" [ngModel]="name" (ngModelChange)="name=$event"/>
// 語法糖解開用法常用於要增加流程 (如 console.log )
<input type="text" [ngModel]="name" (ngModelChange)="doSomethingWhenModelChange($event)" >
一個樣本參考變數相同變數只能用一次,除非在 *ngFor 的 scope 生命週期內。
最常用於 取值 、搭配 *ngIF 。 (不想用ngModel)
' # + 變數 ' , 抓到 HTMLElement 本體 (eg. input.value
),可以對 innerHTML修改
` <input type="text" #input (keyup.enter)="showValue(input)" /> `
目標必須是 Iterable
<ul>
<li *ngFor='let item of items' >
{{item}}
</li>
</ul>
/* items 必須為 Iterable */
傳值 : 外部傳內部
@input 搭配 property binding
@output 類別 : EventEmitter , 搭配 event binding
this.send.emit('sent somethings') // 傳值
(send)="getEvent($event)" 可以取值
HostBinding: 針對整個 component 的屬性(property)去 binding
HostListener: 針對整個 component 的事件去 binding (往上層冒泡傳遞)
參考資料 DOM 的事件傳遞機制:捕獲與冒泡
1. 因為是 class , 先跑constructor(){}
2. OnChanges
3. OnInit
4. DoCheck
5. AfterContentInit
6. AfterContentChecked
7. AfterViewInit
8. AfterViewChecked
9. OnDestory
CD means Change Detection
不同:
view
content
Directive
Component
Structural Directive
參數 [ boolean: first, last, odd, even, ] , [ number: count, index ]
<span [ngStyle]=" { 'font-size' : first ? '30px' : ' ' } ">
{{ item.name }} {{ i+1 }} // {{ count }}
</span>
// [ngStyle]=" 'property': expression(可以用 '? t : f' 三元條件運算式) "
*ngFor=" let item of ( items | async ) "
星號 *
是 <ng-template[ngIf]=" "> 的語法糖Attribute Directive
i18n
常用於格式轉換 Eg. 西元/民國年, 大寫/小寫, 貨幣, ... ,etc.
同一表單單位 (小數點後n位, 小數點前n位, 財務報表統一格式 ... )
時間、日期單位統一 (類似之前自己寫的顯示jQ)
詳細可用轉換 pipe 種類: https://angular.cn/api/common
DecimalPipe
和元件使用時參數命名 {{expression | number }}
不同 FR 千分號為空格,小數點為逗號 output '1 234,71828'
EN 千分號為逗號,小數點為'.' output '1,234.71828'
reference :
Angular-TW : 一次搞懂 RxJS 與 Observable
Angular-TW : [S05E03] RxJS 基本介紹 - Promise & Iterator
var promise01 = new Promise(function(resolve, reject) {
...
});
由於
Promise.prototype.then() ,
Promise.prototype.catch()
方法都回傳 promise,它們可以被串接。
以上是基礎知識,不屬於 Rx.JS。為一般使用JS原有的屬性、特性。
reference Github (code參考,project was generated with angular-cli version 1.0.0-beta.17) https://github.com/chgc/presentation-rxjs
Observable
基本上可以想像和 Promise 類似,但是特別提出區別的地方
Observer : collection of callbacks, values delivered by the Observable.
collection of callbacks 動作如下 :
Subscription: 記錄訂閱(subscribed)的東西(註冊 id),需要取消訂閱,如果沒做動作,會有 memory leak 的問題
Operators : 類似 Lodash.js,轉型、過濾
let button = document.querySelector('button');
Observable.fromEvent(button, 'click').subscribe(() => console.log('Clicked!'));
// 用 Observable 註冊(subscribe) button 事件(fromEvent),這一條線(Marble Diagram)就是持續可監控的事件。
// tem data //
async constructor(){
await Observable.forEach( data=>{} );
}
[Angular線上讀書會] [S01E07] RxJS - 分享 1
Why Rx.js? instead of promise
Ans:方便封裝(module)、lazy loading
EN - jQ docs :
https://api.jquery.com/event.data/
http://api.jquery.com/jquery.each/
練習 Q1 :
用原生js api 寫 點擊(click)增加class控制畫面。
https://github.com/sulco/angular-developer-roadmap/blob/master/angular-dev-roadmap.png
以下為有答案的練習紀錄,原題目網站於上方
You've managed to flatten a tree that's two levels deep, let's try for three! Let's say that instead of a single boxart url on each video, we had a collection of boxart objects, each with a different size and url. Create a query that selects {id, title, boxart} for every video in the movieLists. This time though, the boxart property in the result will be the url of the boxart object with dimensions of 150x200px. Let's see if you can solve this problem with map(), concatAll(), and filter().
There's just more one thing: you can't use indexers. In other words, this is
illegal
:
var itemInArray = movieLists[0];
Furthermore, you're not allowed to use indexers in any of the remaining exercises unless you're implementing one of the five functions. There is a very good reason for this restriction, and that reason will eventually be explained. For now, you'll simply have to accept it on faith that this restriction serves a purpose. :-)
var movieLists = [
{
name: 'Instant Queue',
videos: [
{
id: 70111470,
title: 'Die Hard',
boxarts: [
{ width: 150, height: 200, url: 'http://cdn-0.nflximg.com/images/2891/DieHard150.jpg' },
{ width: 200, height: 200, url: 'http://cdn-0.nflximg.com/images/2891/DieHard200.jpg' },
],
url: 'http://api.netflix.com/catalog/titles/movies/70111470',
rating: 4.0,
bookmark: [],
},
{
id: 654356453,
title: 'Bad Boys',
boxarts: [
{ width: 200, height: 200, url: 'http://cdn-0.nflximg.com/images/2891/BadBoys200.jpg' },
{ width: 150, height: 200, url: 'http://cdn-0.nflximg.com/images/2891/BadBoys150.jpg' },
],
url: 'http://api.netflix.com/catalog/titles/movies/70111470',
rating: 5.0,
bookmark: [{ id: 432534, time: 65876586 }],
},
],
},
{
name: 'New Releases',
videos: [
{
id: 65432445,
title: 'The Chamber',
boxarts: [
{ width: 150, height: 200, url: 'http://cdn-0.nflximg.com/images/2891/TheChamber150.jpg' },
{ width: 200, height: 200, url: 'http://cdn-0.nflximg.com/images/2891/TheChamber200.jpg' },
],
url: 'http://api.netflix.com/catalog/titles/movies/70111470',
rating: 4.0,
bookmark: [],
},
{
id: 675465,
title: 'Fracture',
boxarts: [
{ width: 200, height: 200, url: 'http://cdn-0.nflximg.com/images/2891/Fracture200.jpg' },
{ width: 150, height: 200, url: 'http://cdn-0.nflximg.com/images/2891/Fracture150.jpg' },
{ width: 300, height: 200, url: 'http://cdn-0.nflximg.com/images/2891/Fracture300.jpg' },
],
url: 'http://api.netflix.com/catalog/titles/movies/70111470',
rating: 5.0,
bookmark: [{ id: 432534, time: 65876586 }],
},
],
},
];
這一篇比較長,被視作 Key-Exercise。
單獨拉一篇寫筆記,大概翻譯一下問題,不是很精確,大概的意思 :
你已經順利完成 資料樹 (tree) 的二層(維度)深 合併 為 一層 (維度) ,來試試看三層(維度)吧!
你需要創造query ,蒐集 movieLists 裡, 每一個 video 的 {id, title, boxart} 。其中,boxart 有不同大小和url,目標是一個包含
boxart url
的物件,並且條件是150x200px
請使用 map(), concatAll(), filter() 解決問題此外
var itemInArray = movieLists[0];
這種語法(indexers) 不可以使用
接下來的其他問題也是有一樣的 限制條件
其實會限制語法,是因為這邊練習是為了後面的 Rx.js,也是asynchronous programming的特性。
先試試看解這題吧:
還差一個boxart的條件,而且每一層裡面都包一個array
[ [somethings], [somethings], [somethings] ]
需要用 concatAll() 合併。
完成!
完成...嗎?
注意到,有個小bug : boxarts:[ url ]
,又是一個二維需要合併。
這時候多懷念var itemInArray = movieLists[0];
.... 輕鬆可以解開,可惜被限制使用。
回想一下,var itemInArray = movieLists[0];
是做變數綁定,
把集合內 movieLists,找出 index 的第一個物件 movieLists[0]
綁定在 itemInArray
上,
和某一個函式有點像
[1,2,3].map( x => x+1 )
x
is every item in that collection試著實做看看:
之所以造成最後單獨不能解決的 boxarts:[ url ]
,
是因為先綁定在 video
( 第4行 : some.map ( video
=> somethings ),scrop 被限縮
movieLists.
map( movieList =>
movieList.videos.map( video =>
({
{ someObjs }
})
)
).concatAll()
處理一堆的 array nesting , 三層 -> 一層
加回去 json 格式 (因為如果一開始加,會印不出內容,所以故意現在才加,不影響說明)
注意 scope,這種巢狀範圍鏈 (Scope chain) 很容易搞混:
video.id
, video.title
是在外層 .map( video
=> somethings ) 的 video
底下取值boxart.url
取值對象是 .filter.map(boxart
=> somethings)或許對熟悉的人來說,會有一種「這也要講那麼細?!」的驚訝,不過我理解上,第一次實作確實需要拆到那麼細,希望對閱讀的人也有些幫助。
如果發現任何錯誤,歡迎來訊告知~
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.