持續新增
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的第一個參數的senderproperty 送ready事件連同設定內容回原來送init事件的那個 Window - [Browser] 把設定內容餵給
Elm.Main.fullscreen建立 Elm app,Elm 會自動幫我們把 JSON 轉成 Elm 內部我們定義的 data type