本身動手製做更好用的markdown編輯器-03

這裏文章都是從我的的github博客直接複製過來的,排版可能有點亂. 原始地址  http://benq.im/2015/04/24/hexomd-03/
文章目錄
  1. 1. 系統模塊
  2. 2. 記錄上次打開的文件
  3. 3. 編輯器樣式選擇
    1. 3.1. 樣式修改表單
    2. 3.2. 自動生成select列表
  4. 4. 總結
  5. 5. 附件

上一篇咱們實現了文件的新建,保存,打開功能.css

在這篇裏咱們將實現如下功能:html

  1. 系統模塊,包含一些軟件的設置和存儲功能
  2. 記錄上次打開的文件
  3. 編輯器樣式選擇

系統模塊

跟以前的studio模塊相似,咱們在modules模塊下增長system目錄.

比studio多了model.js文件,用來實現系統模塊的一些功能.git

app.js里加載system模塊angularjs

1
2
3
4
5
6
angular.module('hmd', ['ui.router','hmd.directives','hmd.studio','hmd.system'])
...
//引入模塊
hmd.regModule('studio');
hmd.regModule('system');
...

 

路由、導航欄
angular.js用得不熟,導航欄的狀態根據route來切換一直不知道怎麼實現比較優雅.
我直接在app.js裏增長了一個導航欄切換的方法,每一個route的onEnter事件裏自行調用這個方法.github

1
2
3
4
5
6
//TODO:更優雅的導航欄切換邏輯
hmd.changeStatus = function (state) {
var $navList = $('#navlist');
$navList.find('li').removeClass('active');
$navList.find('.' + state).addClass('active');
};

 

system/route.jsjson

1
2
3
4
5
6
7
8
9
10
11
hmd.system.config(function ($stateProvider, $urlRouterProvider) {
$stateProvider
.state('system', {
url: "/system",
templateUrl: "modules/system/views/system.html",
controller: 'system',
onEnter: function () {
hmd.changeStatus('system');
}
});
});

 

studio/route.jsapi

1
2
3
4
5
...
onEnter: function () {
hmd.changeStatus('studio')
;

}
...

 

而後在index.html裏配置好導航緩存

1
2
3
4
5
6
...
<ul class="nav navbar-nav" id="navlist" >
<li class="studio"><a href="#/studio">編輯器</a></li>
<li class="system"><a href="#/system">系統設置</a></li>
</ul>
...

 

導航欄最終效果:
hexo

記錄上次打開的文件

每次打開文件都會被記住,下次從新啓動程序時將默認打開最後一次打開的文件.app

system設置的讀取和保存

咱們先在system/model.js實現保存和讀取設置的功能.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
var util = require('./helpers/util'),
fs = require('fs'),
system = hmd.system,
//存儲設置的文件
dataFile = system.dataPath + '\\system.json';

//初始化存儲目錄
if (!fs.existsSync(system.dataPath)) {
fs.mkdirSync(system.dataPath);
}

//默認設置
var defaultSystemData = {
//最後一次打開的文件
lastFile: null
};

//讀取設置
system.get = function () {
return $.extend(defaultSystemData,util.readJsonSync(dataFile));
};

//保存設置
system.save = function (data) {
data = data || defaultSystemData;
util.writeFileSync(dataFile, JSON.stringify(data));
};

//設置最後打開的文件
system.setLastFile = function (filepath) {
var systemData = system.get();
systemData.lastFile = filepath;
system.save(systemData);
};

 

system實現了getsave方法,全部的設置都存儲在一個簡單的對象裏,代碼裏並無對這個對象作緩存,每次都是從文件裏讀取,由於這簡單的文件還遠達不到影響讀取速度的狀況.

而後咱們修改editorsetFile方法,暴露setFiled事件給外部使用.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//設置當前文件
setFile:function(filepath){
if(filepath && fs.existsSync(filepath)){
var txt = util.readFileSync(filepath);
this.filepath = filepath;
this.cm.setValue(txt);
this.fire('setFiled',this.filepath);
}
else{
this.filepath = null;
this.cm.setValue('');
this.fire('setFiled');
}
}

 

最後修改studio/directives.jshmdEditor,實現這個功能.

1
2
3
4
5
6
7
8
9
10
studio.directive('hmdEditor', function () {
return function ($scope, elem) {
//讀取最後一次打開的文件
var systemData = hmd.system.get();
hmd.editor.init({el:elem[0]},systemData.lastFile);
//保存最後一次打開的文件
hmd.editor.on('setFiled',function(filepath){
hmd.system.setLastFile(filepath);
});
...

 

編輯器樣式選擇

樣式修改表單

樣式文件在目錄app/lib/codemirror/theme.
目錄裏每個樣式文件表明一種編輯器樣式,還記得當初實現editorinit時,樣式已是經過配置傳入的.

1
2
3
4
5
...
if(options.theme != 'default'){
$('head').append('<link href="lib/codemirror/theme/'+options.theme+'.css" rel="stylesheet" />');
}
...

 

如今咱們只要把theme參數存儲到配置裏,並提供給用戶修改就能夠.

system/model.js裏的默認配置增長一個theme字段.

1
2
3
4
5
6
7
8
9
...
//默認設置
var defaultSystemData = {
//最後一次打開的文件
lastFile: null,
//當前樣式
theme:'ambiance'
};
...

 

修改system/views/system.html模版,增長樣式表單

1
2
3
4
5
6
7
8
9
10
11
12
13
<div class="content studio-wrap">
<form class="system-form" name="systemForm">
<div class="form-group">
<label>編輯器樣式</label>
<select ng-model="systemSetting.theme" name="theme">
<option value="ambiance">ambiance</option>
<option value="mbo">mbo</option>
<option value="neat">neat</option>
</select>
</div>
<button type="submit" class="btn btn-default" ng-click="save(systemSetting)">保存</button>
</form>
</div>

 

這裏的select控件咱們先寫了3個選項.如今先實現這個修改樣式的功能,等完成這個功能後再把選項列表作成自動生成.

對應的system/controllers.js(開發了3天了,終於第一次用到controller了)

1
2
3
4
5
6
system.controller('system', function ($scope) {
$scope.systemSetting = system.get();
$scope.save = function (systemSetting) {
system.save(systemSetting);
};
});

 

controller裏讀取system的數據,並賦值給$scope.systemSetting,用於表單的數據綁定.因爲angular實現了數據的雙向綁定,所以用戶編輯表單時,綁定的數據也會跟着更新.這樣咱們的save方法裏只要將表單綁定的數據保存回system便可.

button按鈕綁定save方法ng-click="save(systemSetting)".

這裏能夠稍微感覺到angular讓咱們節省了不少工做量.

自動生成select列表

修改controller

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var system = hmd.system,
fs = require('fs');
system.controller('system', function ($scope) {
//讀取theme目錄,生成樣式列表
var files = fs.readdirSync('./app/lib/codemirror/theme'),themes={};
files.forEach(function (file) {
if(~file.indexOf('.css')){
file = file.replace('.css','');
themes[file] = file;
}
});
$scope.themes = themes;
$scope.systemSetting = system.get();
$scope.save = function (systemSetting) {
system.save(systemSetting);
};
});

 

theme目錄裏讀取全部樣式列表,生成鍵值對,而後賦值給$scope.themes

修改視圖模版:

1
2
<select name="theme" ng-model="systemSetting.theme"  ng-options="k as v for (k, v) in themes">
</select>

 

ng-options="k as v for (k, v) in themes"是angular的綁定語法

這樣咱們就實現了樣式列表的自動讀取,用戶若是想自定義樣式,只要在app/lib/codemirror/theme目錄新增一個樣式文件,並寫上本身的樣式就能夠在系統設置裏選擇自定義的樣式了.

總結

今天實現了記憶最後一次打開的文件以及樣式選擇的功能,而且第一次使用了angularcontroller,感覺到了angular雙向數據綁定的強大.

咱們的程序又更好用一些了(可是隨着界面變多,又更醜了,太爲難了).

最終效果截圖

附件

本篇程序打包
項目地址

相關文章
相關標籤/搜索