这里文章都是从个人的github博客直接复制过来的,排版可能有点乱. 原始地址 http://benq.im/2015/04/24/hexomd-03/

上一篇我们实现了文件的新建,保存,打开功能.

在这篇里我们将实现以下功能:

  1. 系统模块,包含一些软件的设置和存储功能
  2. 记录上次打开的文件
  3. 编辑器样式选择

系统模块

跟之前的studio模块类似,我们在modules模块下增加system目录.

比studio多了model.js文件,用来实现系统模块的一些功能.

在app.js里加载system模块

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事件里自行调用这个方法.

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.js

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.js

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>
...

导航栏最终效果:

记录上次打开的文件

每次打开文件都会被记住,下次重新启动程序时将默认打开最后一次打开的文件.

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实现了get和save方法,所有的设置都存储在一个简单的对象里,代码里并没有对这个对象做缓存,每次都是从文件里读取,因为这简单的文件还远达不到影响读取速度的情况.

然后我们修改editor的setFile方法,暴露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.js的hmdEditor,实现这个功能.

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.
目录里每一个样式文件代表一种编辑器样式,还记得当初实现editor的init时,样式已经是通过配置传入的.

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目录新增一个样式文件,并写上自己的样式就可以在系统设置里选择自定义的样式了.

总结

今天实现了记忆最后一次打开的文件以及样式选择的功能,并且第一次使用了angular的controller,感受到了angular双向数据绑定的强大.

我们的程序又更好用一些了(但是随着界面变多,又更丑了,太为难了).

最终效果截图

附件

本篇程序打包
项目地址

自己动手制作更好用的markdown编辑器-03的更多相关文章

  1. 自己动手制作更好用的markdown编辑器-01

    这里文章都是从个人的github博客直接复制过来的,排版可能有点乱. 原始地址  http://benq.im   文章目录 1. 简介 2. 项目结构 3. 程序主界面 4. 拖动窗口 5. app ...

  2. 自己动手制作更好用的markdown编辑器-02

    这里文章都是从个人的github博客直接复制过来的,排版可能有点乱. 原始地址 http://benq.im 文章目录 1. 工具条 1.1. 样式 1.2. 工具条截图 2. 状态栏消息 3. 文件 ...

  3. 自己动手开发更好用的markdown编辑器-04(实时预览)

    这里文章都是从个人的github博客直接复制过来的,排版可能有点乱. 原始地址 http://benq.im/2015/04/25/hexomd-04/   程序打包   文章目录 1. 打开新窗口 ...

  4. 自己动手开发更好用的markdown编辑器-07(扩展语法)

    这里文章都是从个人的github博客直接复制过来的,排版可能有点乱. 原始地址 http://benq.im/2015/05/19/hexomd-07/   文章目录 1. 准备工作 2. 目录语法 ...

  5. 自己动手开发更好用的markdown编辑器-06(自动更新)

    这里文章都是从个人的github博客直接复制过来的,排版可能有点乱. 原始地址 http://benq.im/2015/05/12/hexomd-06/   文章目录 1. 自动更新方案 2. 实现 ...

  6. 自己动手开发更好用的markdown编辑器-05(粘贴上传图片)

    这里文章都是从个人的github博客直接复制过来的,排版可能有点乱. 原始地址 http://benq.im/2015/04/28/hexomd-05/   文章目录 1. 七牛云存储 1.1. 系统 ...

  7. 任由文字肆意流淌,更自由的开源 Markdown 编辑器

    对于创作平台来说内容编辑器是十分重要的功能,强大的编辑器可以让创作者专注于创作"笔"下生花.而最好取悦程序员创作者的方法之一就是支持 Markdown 写作,因为大多数程序员都是用 ...

  8. 市面上有没有靠谱的PM2.5检测仪?如何自己动手制作PM2.5检测仪

     市面上能买到的11中常见的pm2.5检测仪 网上大佬实测并不是很准,我这里没测过(全买下来有点贵,贫穷限制了我的想象力) 这些检测仪多数是复合式.多功能的空气质量检测仪.具体就不一一介绍了.这篇文章 ...

  9. 更轻便的markdown 编辑器Typora

    更轻便的markdown 编辑器 Typora 所见即所得的键入方式 https://typora.io 文章来源:刘俊涛的博客 欢迎关注,有问题一起学习欢迎留言.评论.

随机推荐

  1. [linux]压缩、解压命令

    .tar.gz 和 .tgz 解压:tar zxvf FileName.tar.gz 压缩:tar zcvf FileName.tar.gz DirName tar 解包:tar xvf FileNa ...

  2. NOIP2018提高组模拟题(四)

    能量(energy) Description ​ 有一块能量田,它的形状是 n*m的矩形,每一个格子上都有一个能量值 a[x][y] (可正可负).一块矩形田的能量定义为它的每个格子的能量值之和. ​ ...

  3. [BZOJ2226]LCMSum

    转化一下,$\sum\limits_{i=1}^n[i,n]=n\sum\limits_{i=1}^n\dfrac i{(i,n)}$ 枚举$d=(i,n)$,上式变为$n\sum\limits_{d ...

  4. 【莫队算法】【权值分块】bzoj3339 Rmq Problem

    如题. #include<cstdio> #include<algorithm> #include<cmath> using namespace std; #def ...

  5. Mysql中的JSON系列操作函数

    前言 JSON是一种轻量级的数据交换格式,采用了独立于语言的文本格式,类似XML,但是比XML简单,易读并且易编写.对机器来说易于解析和生成,并且会减少网络带宽的传输. JSON的格式非常简单:名称/ ...

  6. [CF627D]Preorder Test

    题目大意: 一个$n(n\le2\times10^5)$个结点的树,每个结点有一个权值$w_i$.可以任选一点为根,并选择一些结点交换其子结点的顺序,使得该树DFS序上第$m$个结点的权值最大.求最大 ...

  7. STL之search

    描述 使用STL中的search函数,判断一个序列是否是另一个序列的子序列. 部分代码已经给出,请补充完整,提交时请勿包含已经给出的代码. int main() { vector<int> ...

  8. TZOJ 5396: 集五福过大年

    描述 又是一年春来到,伴随着春节,支付宝的“集五福”活动又开始了,五福分别是“爱国福”.“富强福”.“和谐福”.“友善福”和“敬业福”,五张不同的福卡可以合成一张“五福到”,crq也扫了不少福,这么多 ...

  9. Jquery中的ajax应用(第九章PPT)

    <%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1&q ...

  10. Android Studio 下使用git -- 个人,本地版本控制

    第一步:下载安装git 下载地址 : https://git-scm.com/downloads 第二步:Android Studio 下配置git路径. 配置之后,Test弹出如下成功的提示即可. ...