持續新增
Elm 裡的每個 Native module 就只是一個擁有許多 method 的 object,跟 CMD 的 exports
一樣,但存放物件的變數需要按照 Elm 的規則命名:
- 基本規則:
_{github_user_name}${github_repo_name}${module_name}
- 使用
_
替代-
(elm-lang
=>elm_lang
) module_name
用_
替代.
(Native.Electron.Window
=>Native_Electron_Window
)
大致上會長這樣:
var _user$repo$Native_ModuleName = {
func: function () {}
};
為了避免 module 內部使用的變數污染全局,通常會使用 IIFE:
var _user$repo$Native_ModuleName = (function () {
return {
func: function () {}
};
})();
Elm 提供了 F2 ~ F9 8 個 function(src/Pipeline/Generate.hs#L244-L326),FN
的 N
代表參數個數,舉個例子:
var f1 = a => b => a + b;
var f2 = F2((a, b) => a + b);
// f1, f2 相同
Elm 也提供了執行 Curry 化的 Function 的 Function,A2 ~ A9 (src/Pipeline/Generate.hs#L328-L375):
var f = F2((a, b) => a + b);
A2(f, 1, 2) === f(1)(2);
_elm_lang$core$Native_Scheduler.nativeBinding(cb => {
// 失敗時:
// 這邊假設 Elm 已經有一個叫做 `Error` 的 Constructor:`type Error = Error String`
cb(_elm_lang$core$Native_Scheduler.fail({ ctor: 'Error', _0: err.message }));
// 成功時:
// 回傳資料的方式同失敗時的處理方式,沒有資料回傳時回傳 `_Tuple0`
cb(_elm_lang$core$Native_Scheduler.succeed({ ctor: '_Tuple0' }));
});
https://gist.github.com/poying/45e6b176017d3a797109289750041513
使用 Electron 製作 Desktop application 一定會有需要保留使用者設定的時候,但這些動作都是在 Elm architecture 之外,在 Elm 裡面不好使用,勢必要想一個比較漂亮的方式跟 Elm architecture 串在一起。Elm 提供兩種方式跟 JavaScript 溝通。
兩種方法都可以。但 port 只能回傳 Cmd msg
,無法知道成功或失敗。native module 可以建立 Task
,Task
的好處在於可以使用 andThen
、onError
等 function 跟其他 Task
串聯,而且可以區分成功、失敗的 Cmd msg
,所以我是傾向於都寫 native module。
- [Node] 建立 Electron 的 Window
- [Node] 聽
ipcMain
的init
事件 - [Browser] 聽
ipcRenderer
的ready
事件 - [Browser] 透過
ipcRenderer
送init
事件 - [Node] 讀取並 parse 檔案內容
- [Node] 透過
init
事件listener
的第一個參數的sender
property 送ready
事件連同設定內容回原來送init
事件的那個 Window - [Browser] 把設定內容餵給
Elm.Main.fullscreen
建立 Elm app,Elm 會自動幫我們把 JSON 轉成 Elm 內部我們定義的 data type