Step2-知其然:一文講透Obsidian插件DataviewJS

Obsidian&Zettelkasten&LYT構建第二大腦系列文章總目錄(持續更新)

? ? ? 我們接著上一篇,Step1-先預熱:一文講透Obsidian插件DataviewJS,繼續講解第二步:知其然。作為熱身,我們還是先看一段相對簡單一點的代碼:

示例代碼

? ? ? 這段代碼的運行結果是:在筆記庫vault中,把標簽為“book”的筆記找出來,然后按照書籍的類型進行分組,每組用一個表格的形式展示出來,表格的表頭包含“姓名name”、“閱讀時間TimeRead”、“評分Rating”,幾個字段,表格的內容按照書籍評分降序排列。執行效果如下:

執行結果

? ? ? 分析代碼,格式排版很重要,我的習慣是把他們放到代碼編輯器里進行排版,這樣便于自己閱讀和理解,這里選用Sublime Text來編寫和閱讀代碼。具體怎么用,后面找機會單獨介紹,排版以后的代碼如下:

格式化后的代碼--可讀性強

? ? ? 這么看順眼多了,也更好理解。整段代碼是嵌入在obsidian筆記中的,使用“```davaviewjs”做開頭,使用“```”做結尾,里面放的是javascript代碼,準確的說應該是typerscript代碼。因為Dataview的作者使用的typerscript來開發的Dataview插件。這個從github上的項目文件后綴就可以看出來,都是以*.ts結尾的。

typerscript文件

? ? ? 代碼源文件src下面包括多個目錄,隨便打開一個里面的文件都是以*.ts結尾。這里api和data兩個目錄,后面我們會重點介紹里面幾個關鍵的源代碼文件。看源代碼可以在瀏覽器的github里打開直接看,不過我強烈建議把整個源碼下載到本地,然后用Sublime Text導入整個項目,借助代碼編輯器讀源代碼的效果會高出數倍。

? ? ? ?? 首先是一個for語句,在typerscript的for循環語句有兩種形式,這里采用的是常用的for...of語法。意思就是在一個集合中逐一取出一個元素進行遍歷,針對取出的這個元素,做一些處理動作。for循環體()里的部分是對遍歷的集合做一個條件限制。

? ? ? ?? let 是一個定義變量的關鍵詞,類似javascript里面的var,不過let的用法更靈活,它可以定義任意類型的變量,比如

?let aaa : string = "hello"

這里就定義了一個string字符串類型的變量叫aaa。還可以定義別的,比如

?let dance = function(name : string) {return "Look! ${name} is dancing!"}

這里let就定義了一個函數變量dance,這個函數定義用到了function關鍵詞,在()里定義了一個需要輸入的參數name,而且明確name的類型為string字符串,在{}里定義了函數要做的動作,return是關鍵詞,表示整個函數運行完后返回的結果。這里函數返回的是一個字符串,一句話:XXX在跳舞,這里的XXX因為在""內,所以使用了簡寫的方式,使用${}的方式直接調用了參數name的值,比如函數是dance("Jack"),那么結果輸出就是:"Look! Jack is dancing!""。當然typerscript在定義函數時有好幾種不同的方式,比如剛才的定義也可以寫成:

?let dance => (name : string): "Look! ${name} is dancing!"

看上去是不是簡潔了很多,這是使用=>定義函數的方式,在typescript的代碼里十分常見,要習慣。其實,typerscript和JavaScript相比,代碼定義更嚴格,它是對JavaScript的擴充,針對泛型的使用更高頻,代碼更簡潔,但有時候過度簡潔讀起來不是特別好理解。比如還是這句,如果用泛型來定義可以寫成:

?let dance<T> => (args : T) : T

這里使用泛型<T>的好處就是可以不用事先確定參數的類型和返回的類型,函數的適用范圍更靈活,后面我們講解dataviewAPI的部分源碼時會經常碰到這樣的情況。一般我們寫程序,比如java等,編程的過程都是針對值進行編程,typerscript前進了一步,它能夠針對類型進行編程。比如還是這個例子,我們可以定義一個自定義的新類型danceType,讓它把這種函數形態給記錄下來以后隨時使用:

?type danceType<T> = (args : T) => T

type是一個關鍵詞,可以理解為給一個自定義的數據類型起了一個別名,這個就是給一個自定義的函數類型的一個數據類型,起了個別名叫danceType。或者舉個簡單的例子:

?type mystr = string

就是給string類型另外起了一個別名叫mystr,實際上還是同一個類型。要義就是通過這種方式對類型進行編程了。結合上泛型,就變得十分靈活,不過可讀性也確實燒腦了。讀源碼的時候這種類型+泛型的代碼很多,需要熟悉和習慣。后面我會留一些配套的文章,供大家慢慢學習熟悉。

? ? ? ?? 繼續看例子:for的()里的意思,使用let定義了一個group變量,因為group放在了for...of中間,所以group就是of后面跟著的那個集合中取出的一組元素,確切的說就是

?dv.pages("#book").groupBy(p => p.genre)?

所代表的一組元素集合,是一個數據結構。這里要弄清含義,就需要看看github上作者給出的DataviewAPI了,里面給出了常用的一些函數的說明,位置在首頁的概述部分:

打開后,可以看到一些常用的函數:

DataviewAPI頁面
API中文翻譯
API英文原文

我的英文不好,所以經常是用翻譯軟件,中英文來回切換著看,這樣效率更高一些。

? ? ? 從API文檔里可以看到,dv是在obsidian筆記中調用Dataview的一個代名詞,一般的函數都是從dv.XXX開始的。dv.pages(source),這個函數可以根據傳入參數source的不同返回符合參數條件的筆記集合,主要支持兩種方式:按標簽和按筆記所在的目錄或者路徑,這些條件可以通過與或非進行條件組合。從作者給的例子里可以看出函數返回的是一個筆記的集合pages,里面會有一篇一篇的筆記page。實際上從這個API文檔中我們得到的確切信息不足,比如返回的結果到底是什么類型,看不出來,只能猜出大概的意思是一個筆記的集合,但是具體的數據類型并不清楚,這種不清晰會給我們后續理解代碼帶來很大的障礙,編程不是感覺怎么怎么樣,而且確切的推理和推導過程,計算機代碼是嚴絲合縫的,不是靠猜的。要想做到這點,就需要更進一步追蹤進去看源代碼了,這個我們放到后面第三步再說,這里先意會吧。其他函數的意思大家自己去看API,不再逐個做解釋。

? ? ? typescript支持函數嵌套的寫法,前一個函數返回的對象可以繼續調用他所支持的函數繼續一層層調用下去,所以會出現很多個函數.函數.函數這樣一直連續調用一長段,很正常,習慣就好。在這里dv.pages()函數返回筆記頁面構成的集合對象后,繼續調用了一個groupBy函數進行分組,groupBy()內部的寫法是一個典型的泛型參數傳參的寫法,這個后面我們看源代碼的時候在繼續深究,這里只需要明白,groupBy()函數是將前面的筆記集合中的元素,用genre分類屬性作為對筆記集合的分組條件,這樣返回的結果就是按照分類把書籍分成了幾組,所以for循環的次數,和分組后的組數是一致的,看一眼for循環體內的句子,我們大概能猜到,每組書籍應該是以表格形式來呈現的,有幾組就有幾張表格。

? ? ? ?? for循環體內的語句,不展開,使用了dv.head()與dv.table()的方式來輸出三級標題和畫表格。這里需要重點提兩個地方:

? ? ? 第一是group.key的用法。group在前面提了,是每次for循環從筆記集合體遍歷出來的一個筆記子集合,由于前面用了genre屬性做分組,分組保存的形式,類似key、value的方式,key保存的是分組的genre屬性的值,value保存的是某個分組下的筆記的集合。所以,group.key的值就是genre分類,把它當成一個三級標題輸出。

? ? ? 第二個是dv.table()的用法,這里不展開講,用到了排序和map構造二維數組作為填充表格的內容,這個也放到第三步里我們看源代碼來詳細解讀。

? ? ? 第二步,知其然的部分就說到這,篇幅有限,下篇繼續。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,797評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,179評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,628評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,642評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,444評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,948評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,040評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,185評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,717評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,602評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,794評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,316評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,045評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,418評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,671評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,414評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,750評論 2 370

推薦閱讀更多精彩內容