-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.html
367 lines (275 loc) · 39.6 KB
/
index.html
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>mosquito的个人博客</title>
<meta name="author" content="mosquito">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta property="og:site_name" content="mosquito的个人博客"/>
<meta property="og:image" content="undefined"/>
<link href="/favicon.png" rel="icon">
<link rel="alternate" href="/atom.xml" title="mosquito的个人博客" type="application/atom+xml">
<link rel="stylesheet" href="/css/style.css" media="screen" type="text/css">
<!--[if lt IE 9]><script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script><![endif]-->
</head>
<body>
<header id="header" class="inner"><div class="alignleft">
<h1><a href="/">mosquito的个人博客</a></h1>
<h2><a href="/"></a></h2>
</div>
<nav id="main-nav" class="alignright">
<ul>
<li><a href="/">Home</a></li>
<li><a href="/archives">Archives</a></li>
</ul>
<div class="clearfix"></div>
</nav>
<div class="clearfix"></div></header>
<div id="content" class="inner">
<div id="main-col" class="alignleft"><div id="wrapper">
<article class="post">
<div class="post-content">
<header>
<div class="icon"></div>
<time datetime="2015-12-20T12:15:24.000Z"><a href="/2015/12/20/nodejs学习-一个简单的todoList/">2015-12-20</a></time>
<h1 class="title"><a href="/2015/12/20/nodejs学习-一个简单的todoList/">nodejs学习-一个简单的todoList</a></h1>
</header>
<div class="entry">
<h2 id="u6DFB_u52A0_u89C6_u56FE"><a href="#u6DFB_u52A0_u89C6_u56FE" class="headerlink" title="添加视图"></a>添加视图</h2><p>需要添加的视图有</p>
<ul>
<li>显示所有任务的视图(也是首页视图)</li>
<li>添加任务的视图</li>
<li>编辑任务的视图,这个可以和添加任务视图共用</li>
</ul>
<p>下面是首页视图index.jade<br><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">mixin taskItem(tname, time, id)</span><br><span class="line"> li= tname + ' ' + time </span><br><span class="line"> a(href='/editTask/#{id}') 编辑</span><br><span class="line"> a(href='/delTask/#{id}/delete') 删除</span><br><span class="line"></span><br><span class="line">extends head</span><br><span class="line"></span><br><span class="line">block content</span><br><span class="line"> a(href='/newTask') 添加任务</span><br><span class="line"> if (taskList.length)</span><br><span class="line"> ul </span><br><span class="line"> each task in taskList</span><br><span class="line"> +taskItem(task.tname, task.time, task.id)</span><br><span class="line"> else</span><br><span class="line"> p 你还没有任何任务</span><br></pre></td></tr></table></figure></p>
<p>写的时候发现使用mixin的两点注意</p>
<ol>
<li>mixin前面不要加’-‘,加’-‘的说是在服务器端的代码,这样下面的引用会报错undefined</li>
<li>使用mixin时的加号不能省去,否则会是字符串输出,mixin没有用</li>
</ol>
<p>添加和编辑任务的视图task.jade如下<br><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line">//- Used for editing and creating tasks</span><br><span class="line">extend head</span><br><span class="line"></span><br><span class="line">block content</span><br><span class="line"> -if (task)</span><br><span class="line"> -tname = task.tname</span><br><span class="line"> -time = task.time</span><br><span class="line"> -tid = task.id</span><br><span class="line"> -else</span><br><span class="line"> -tname = ''</span><br><span class="line"> -time = ''</span><br><span class="line"> -tid = ''</span><br><span class="line"> form(action='/save/#{tid}',method='post')</span><br><span class="line"> span 任务内容</span><br><span class="line"> input(name='tname',value=tname)</span><br><span class="line"> br</span><br><span class="line"> span 时间</span><br><span class="line"> input(type='time',name='time',value=time)</span><br><span class="line"> br</span><br><span class="line"> -if (task)</span><br><span class="line"> input(type='hidden',name='_method',value='PUT')</span><br><span class="line"> br</span><br><span class="line"> input(type='submit')</span><br></pre></td></tr></table></figure></p>
<p>注意到了以下几点</p>
<ol>
<li>在input的括号里面并不能使用三目运算符,所以只好在之前加一个判断</li>
<li>if/else语句块去掉前面’-‘后会报错,但是不知道原因</li>
<li>在url等带引号的字符串中引用输出变量,既可以使用加号连接,也可以使用#{}将变量名包裹起来,有点像php的$</li>
</ol>
<p>同样的也遇到了一些问题。根据书本上使用了_method来转换http方法,因为一般的只支持post和get方法,而在这里需要用到创建、添加、删除多个功能,一个方法可能不够路由识别。只要在form中添加<br><figure class="highlight stylus"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="title">input</span><span class="params">(type=<span class="string">'hidden'</span>,name=<span class="string">'_method'</span>,value=<span class="string">'PUT'</span>)</span></span></span><br></pre></td></tr></table></figure></p>
<p>就可以方便的实现http方法转换。<br>但是最后由于删除的功能只是一个a标签不可能用form,才想到可以再在url后面添加’/delete’,’/edit’等等也没有问题的。<br>同样因为express 4.x移除了method-override中间件,所以必须要自行安装引入。但是调试了半天才终于在github上一个已经关闭的issue找到了答案:必须要用1.0版的才支持这种方法。即使用<br><figure class="highlight nimrod"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install --save <span class="keyword">method</span>-override@<span class="number">1</span></span><br></pre></td></tr></table></figure></p>
<p>来安装旧版本。亏我搞了半个下午没搞出来,居然是版本问题。</p>
<h2 id="u6DFB_u52A0mongodb"><a href="#u6DFB_u52A0mongodb" class="headerlink" title="添加mongodb"></a>添加mongodb</h2><p>新建一个mongodb.js文件,通过以下几个步骤将mongodb引入使用(在此之前需要安装mongoose)</p>
<ul>
<li>通过require语句将mongoose包含进来</li>
<li><p>连接数据库,数据库如果不存在会自动创建</p>
<figure class="highlight perl"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">mongoose.<span class="keyword">connect</span>(<span class="string">'mongodb://localhost/todo'</span>);</span><br></pre></td></tr></table></figure>
</li>
<li><p>创建一个schema,这规定了数据存储的结构</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> Schema = mongoose.Schema;</span><br><span class="line"><span class="keyword">var</span> Task = <span class="keyword">new</span> Schema({</span><br><span class="line"> task: <span class="built_in">String</span>,</span><br><span class="line"> time: <span class="built_in">String</span> <span class="comment">// 发现用Date很傻逼</span></span><br><span class="line">});</span><br></pre></td></tr></table></figure>
</li>
<li><p>之后用该schema创建一个model,就可以通过该model进行数据库相关操作</p>
<figure class="highlight gradle"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">var <span class="keyword">task</span> = mongoose.model(<span class="string">'task'</span>, <span class="keyword">Task</span>);</span><br></pre></td></tr></table></figure>
</li>
<li><p>最后输出task内容,需要操作数据库时只要将该文件引入即可</p>
<figure class="highlight openscad"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">module</span>.<span class="title">exports</span> =</span> task;</span><br></pre></td></tr></table></figure>
</li>
</ul>
<h2 id="u6DFB_u52A0_u8DEF_u7531"><a href="#u6DFB_u52A0_u8DEF_u7531" class="headerlink" title="添加路由"></a>添加路由</h2><p>一共就是首页展示任务、添加任务、删除任务、编辑任务几个路由。</p>
<p>首页的展示只要使用find方法找到所有的task并输出就可以了,这里传入的docs就是找到的结果,有那么一点像ajax里面服务器返回内容,同样是参数传入并调用的。db是引入的mongoose model。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* GET task list */</span></span><br><span class="line">router.get(<span class="string">'/'</span>, <span class="function"><span class="keyword">function</span>(<span class="params">req, res, next</span>) </span>{</span><br><span class="line"> req.flash(<span class="string">'info'</span>, <span class="string">'fuck you'</span>);</span><br><span class="line"> db.find({}, <span class="function"><span class="keyword">function</span>(<span class="params">err, docs</span>) </span>{</span><br><span class="line"> res.render(<span class="string">'index'</span>, {</span><br><span class="line"> title: <span class="string">'Task list'</span>,</span><br><span class="line"> taskList: docs</span><br><span class="line"> });</span><br><span class="line"> });</span><br><span class="line"></span><br><span class="line">});</span><br></pre></td></tr></table></figure>
<p>添加任务这里就涉及到两个路由了。首先是点击“添加任务”的路由,这个很简单,就是直接调用task.jade。还有就是在填写完表单之后点击提交按钮的路由,这个涉及到了添加记录的操作</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* save task */</span></span><br><span class="line">router.post(<span class="string">'/save'</span>, <span class="function"><span class="keyword">function</span>(<span class="params">req, res, next</span>) </span>{</span><br><span class="line"> <span class="keyword">var</span> newTask = <span class="keyword">new</span> db({</span><br><span class="line"> tname: req.body.tname,</span><br><span class="line"> time: req.body.time</span><br><span class="line"> });</span><br><span class="line"> newTask.save(<span class="function"><span class="keyword">function</span>(<span class="params">err</span>) </span>{</span><br><span class="line"> <span class="keyword">if</span> (!err) {</span><br><span class="line"> req.flash(<span class="string">'info'</span>, <span class="string">'successly add a task'</span>);</span><br><span class="line"> res.redirect(<span class="string">'/'</span>);</span><br><span class="line"> }</span><br><span class="line"> });</span><br><span class="line">});</span><br></pre></td></tr></table></figure>
<p>首先要实例化一个model,以json的形式传入内容,内容的形式是必须和之前创建的Schema完全对应的。之后只要调用save方法就可以将记录保存到数据库中去了。<br>另外这里的req.body是json形式传入的所以操作很方便。</p>
<p>编辑任务的话由于是从首页点击进入编辑界面的,所以也需要两个路由。一开始想到应该不需要传入文章id,但是后来发现这样根本不可能。如果有DOM的支持,还可以直接从html中获取任务内容,但是node里面并没有DOM,所以还是只能用id来操作。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* edit task */</span></span><br><span class="line">router.get(<span class="string">'/editTask/:id'</span>, <span class="function"><span class="keyword">function</span>(<span class="params">req, res, next</span>) </span>{</span><br><span class="line"> db.findById(req.params.id, <span class="function"><span class="keyword">function</span>(<span class="params">err, doc</span>) </span>{</span><br><span class="line"> res.render(<span class="string">'task'</span>, {</span><br><span class="line"> title: <span class="string">'edit task'</span>,</span><br><span class="line"> task: doc</span><br><span class="line"> });</span><br><span class="line"> })</span><br><span class="line">});</span><br></pre></td></tr></table></figure>
<p>mongoose提供了一个findById方法,可以通过id找到相应的记录。id是每个条目在插入数据库时自动生成的,只要在首页任务展示的时候取到了某个记录,就可以取到任务相关信息以及id。有了id就可以加入到a标签的链接中,这样每个记录都有不同的链接,就可以通过链接中的id参数找到数据库中的记录。</p>
<p>进入到编辑视图中编辑完成点击提交按钮之后的路由与上面的比较相似,同样需要找到对应的记录,然后以json形式传入内容,只不过这里不再像创建新任务那样要创建新的model实例,而是直接对传入的doc进行更改。更改完成再调用save方法就可以完成修改。如果不找到原有记录而是重新创建一个实例并直接save的话是会重新创建一条记录的,即使内容和修改之前的完全一样。</p>
<p>删除任务是在首页点击链接实现的操作,同样要用findById方法找到记录,然后只要调用remove方法就可以删除记录。</p>
<p>所有的操作完成之后都需要再回到首页,使用<br><figure class="highlight stylus"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">res.<span class="function"><span class="title">redirect</span><span class="params">(<span class="string">'/'</span>)</span></span></span><br></pre></td></tr></table></figure></p>
<p>在路由的回调函数中设置重定向。</p>
<p>另外我在所有视图都引用了的head.jade里面加入了提示信息,使用到了connect-flash中间件,同样也是在express 4.x中移除了的。关于connect-flash的内容在另外一篇日志中提到了,不再多写。</p>
</div>
<footer>
<div class="clearfix"></div>
</footer>
</div>
</article>
<article class="post">
<div class="post-content">
<header>
<div class="icon"></div>
<time datetime="2015-12-18T09:04:32.000Z"><a href="/2015/12/18/关于中间件connect-flash/">2015-12-18</a></time>
<h1 class="title"><a href="/2015/12/18/关于中间件connect-flash/">关于express中间件connect-flash</a></h1>
</header>
<div class="entry">
<p>最近按照《nodejs入门经典》做demo,做到了第8章的闪出消息例子,实在是被搞的不行。各种测试了一整天,终于找到了解决方案。</p>
<h2 id="connect-flash_u6982_u5FF5"><a href="#connect-flash_u6982_u5FF5" class="headerlink" title="connect-flash概念"></a>connect-flash概念</h2><p>一个express的中间件,通过将消息存储在session中,使得在不同页面之间跳转时消息内容可以共享。connect-flash支持自定义信息类型如info/error/success等等。通过在node路由的回调函数中调用<br><figure class="highlight vim"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">res</span>.flash(<span class="string">'info'</span>, content);</span><br></pre></td></tr></table></figure></p>
<p>就可以直接在页面的视图中通过<br><figure class="highlight fix"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="attribute">p</span>=<span class="string"> flash.info</span></span><br></pre></td></tr></table></figure></p>
<p>这样的方式来显示消息内容。<br>为什么不用alert?我一开始也这么想,但是alert是浏览器提供的方法,在这里没有用武之地啊。</p>
<h2 id="u8270_u96BE_u7684_u8C03_u8BD5_u8FC7_u7A0B"><a href="#u8270_u96BE_u7684_u8C03_u8BD5_u8FC7_u7A0B" class="headerlink" title="艰难的调试过程"></a>艰难的调试过程</h2><p>书本中版本的express应该是很简单的,只要在app.js中添加<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">app.use(express.cookieParser()); </span><br><span class="line">app.use(express.session({ </span><br><span class="line"> secret: <span class="string">'xxxx'</span> <span class="comment">// 随机的秘钥,自由设定 </span></span><br><span class="line">}););</span><br></pre></td></tr></table></figure></p>
<p>然后就像上面说的那样可以成功操作了。 </p>
<p>然而,对于最新4.x版本的express,事情就没有那么简单。<br>首先,最新版express剥离了connect-flash,也就是这个闪出消息中间件。<br>其次,express-session也被剥离了,这意味着session也不被默认支持了。<br>之后,问题才刚刚开始。 </p>
<p>好的,我就像书上那样做了,于是控制台报错:”ReferenceError: flash is not defined”。<br>百度,好,是没有connect-flash,并且还要在app.js添加<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> flash = <span class="built_in">require</span>(<span class="string">'connect-flash'</span>); </span><br><span class="line">app.use(flash());</span><br></pre></td></tr></table></figure></p>
<p>好,试试再跑一下。 </p>
<p>于是,继续报错”Session is not defined”。<br>好吧,是没有connect-session中间件。装好并require引入依赖之后npm start正常,但控制台多了两行字<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">express-session deprecated <span class="literal">undefined</span> xxxx </span><br><span class="line">express-session deprecated <span class="literal">undefined</span> xxxx</span><br></pre></td></tr></table></figure></p>
<p>这不能忍对吧,于是百度了下,发现是session的配置不完整,人家的配置都有很多项目,而我的只有secret一项。好的,于是更改配置。<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">app.use(session({ </span><br><span class="line"> secret: <span class="string">'nothing'</span>, </span><br><span class="line"> store: <span class="keyword">new</span> MongoStore({ </span><br><span class="line"> db: <span class="string">'todo'</span> </span><br><span class="line"> }), </span><br><span class="line"> resave: <span class="literal">true</span>, </span><br><span class="line"> saveUninitialized: <span class="literal">true</span> </span><br><span class="line">}));</span><br></pre></td></tr></table></figure></p>
<p>这里todo是我的数据库名。<br>再次启动,又开始报错”MongoStore is not defined”。<br>得,又是中间件问题,好,安装,require添加依赖。<br><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">SyntaxError:<span class="operator"><span class="keyword">Use</span> <span class="keyword">of</span> const <span class="keyword">in</span> <span class="keyword">strict</span> <span class="keyword">mode</span>.</span></span><br></pre></td></tr></table></figure></p>
<p>这是逗我吗,你自己写’use strict’又自己违反规定?<br>于是我很高兴地帮助作者删掉了’use strict’,继续愉快的报错’prop is not defined’。<br>感觉已经没办法了,于是我再次机智地在github上找到了connect-mongo,看了他的官方说明,并没有找到解决办法。于是,我在issue里面像作者提问了。<br>然后我就傻逼了。</p>
<p>作者的确回复了我,说如果你的node版本比较低的话应该<br><figure class="highlight stylus"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="title">require</span><span class="params">(<span class="string">'connect-mongo/es5'</span>)</span></span></span><br></pre></td></tr></table></figure></p>
<p>而不是<br><figure class="highlight stylus"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="title">require</span><span class="params">(<span class="string">'connect-mongo'</span>)</span></span></span><br></pre></td></tr></table></figure></p>
<p>我再把说明文档看了一遍,上面对老版本node有特别说明,解决方法也有。 </p>
<p>啊……</p>
<p>原来我的node版本这么老了啊</p>
<figure class="highlight livecodeserver"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Connection strategy <span class="operator">not</span> found <span class="keyword">at</span> <span class="built_in">new</span> MongoStore.</span><br></pre></td></tr></table></figure>
<p>新的错误。<br>再次在github上找,并没有结果,也再不敢直接就去给作者提问了。<br>于是打开了connect-mongo源码。<br>找到了一堆判断语句,和说明文档对应一下分别是使用不同的数据库连接的判断语句。<br>其中有一个是数据库url判定的,并没有找到db相关的。于是把<br><figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">db:</span> <span class="string">'todo'</span></span><br></pre></td></tr></table></figure></p>
<p>改成了url<br><figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">url:</span> <span class="string">'mongodb://localhost:todo'</span></span><br></pre></td></tr></table></figure></p>
<p>于是,终于好了。</p>
<p>我在index的路由中直接加入<br><figure class="highlight actionscript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">req.flash(<span class="string">'info'</span>, <span class="string">'fuck'</span>);</span><br></pre></td></tr></table></figure></p>
<p>试图在index.jade中通过flash.info获取它,但是提示’Cannot read property ‘info’ of undefined’。 </p>
<p>再后来通过回调函数中添加<br><figure class="highlight stylus"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">res<span class="class">.locals</span><span class="class">.flash</span> = req.<span class="function"><span class="title">flash</span><span class="params">()</span></span></span><br></pre></td></tr></table></figure></p>
<p>res.locals看起来应该是本地变量声明。<br>这样的话就可以正常在index.jade中访问到flash.info了,因为req.flash()返回结果是json。 </p>
<p>等等,这样的话我还要用connect-flash干嘛,直接用<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">req.session.xxx = <span class="string">'xx'</span>; </span><br><span class="line">res.locals.xxx = req.session.xxx;</span><br></pre></td></tr></table></figure></p>
<p>不就好了吗?</p>
<p>但是我不能忍。 </p>
<p>于是我就把connect-flash的文件给改了,加了一行代码。改完之后,终于在首页得到了输出,而且路由中只要用req.flash()声明就好了。插件也是可以改的嘛对吧。</p>
<h2 id="u9519_u8BEF_u6392_u9664_u603B_u7ED3"><a href="#u9519_u8BEF_u6392_u9664_u603B_u7ED3" class="headerlink" title="错误排除总结"></a>错误排除总结</h2><h3 id="express_4-x_u5F15_u5165session_u7684_u65B9_u6CD5_uFF1A"><a href="#express_4-x_u5F15_u5165session_u7684_u65B9_u6CD5_uFF1A" class="headerlink" title="express 4.x引入session的方法:"></a>express 4.x引入session的方法:</h3><ol>
<li>安装express-session并在app.js中引入依赖</li>
<li>安装connect-mongo并在app.js中引入依赖,node版本在0.12以下的则需要<figure class="highlight stylus"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="title">require</span><span class="params">(<span class="string">'connect-mongo/es5'</span>)</span></span></span><br></pre></td></tr></table></figure>
</li>
</ol>
<p>因为还不支持es6</p>
<ol>
<li><p>按以下格式引入session,当然,还有更多可选参数,可以参见官方文档</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">app.use(session({ </span><br><span class="line"> secret: <span class="comment">// your random key here, </span></span><br><span class="line"> store: <span class="keyword">new</span> MongoStore({ </span><br><span class="line"> url: <span class="string">'mongodb://localhost:todo'</span> <span class="comment">// your database address </span></span><br><span class="line"> }), </span><br><span class="line"> resave: <span class="literal">true</span>, </span><br><span class="line"> saveUninitialized: <span class="literal">true</span> </span><br><span class="line">}));</span><br></pre></td></tr></table></figure>
</li>
<li><p>这样就可以在路由的回调函数中使用req.session了</p>
</li>
</ol>
<h3 id="connect-flash_u7684_u4F7F_u7528_u65B9_u6CD5_uFF08express_4-x_uFF09"><a href="#connect-flash_u7684_u4F7F_u7528_u65B9_u6CD5_uFF08express_4-x_uFF09" class="headerlink" title="connect-flash的使用方法(express 4.x)"></a>connect-flash的使用方法(express 4.x)</h3><p>如果真的不用改文档可以使用的话……</p>
<ol>
<li>安装connect-flash并在app.js中引入依赖</li>
<li>引入session</li>
<li><p>在路由的回调函数中使用req.flash传入消息类型(主要在要添加样式的时候有区别)和内容</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">router.get(<span class="string">'/'</span>, <span class="function"><span class="keyword">function</span>(<span class="params">req, res, next</span>) </span>{ </span><br><span class="line"> req.flash(<span class="string">'info'</span>, <span class="string">'hello world'</span>); </span><br><span class="line">});</span><br></pre></td></tr></table></figure>
</li>
<li><p>在jade模板中就可以通过flash.info/flash.error访问到提示内容,而且由于session的关系可以在不同页面之间跳转的时候也能得到同步的信息</p>
</li>
</ol>
<h2 id="u4E00_u4E9B_u6536_u83B7_u548C_u542F_u793A"><a href="#u4E00_u4E9B_u6536_u83B7_u548C_u542F_u793A" class="headerlink" title="一些收获和启示"></a>一些收获和启示</h2><p>如果在使用中间件的时候遇到错误</p>
<ol>
<li>百度(当然也会有cnode社区的内容)</li>
<li>官方文档</li>
<li>issue里面找或者问</li>
<li>看源码</li>
</ol>
<p>表示nodejs路漫漫,更新这么快真的好吗,书本完全跟不上节奏啊!</p>
</div>
<footer>
<div class="clearfix"></div>
</footer>
</div>
</article>
<article class="post">
<div class="post-content">
<header>
<div class="icon"></div>
<time datetime="2015-12-07T14:57:19.000Z"><a href="/2015/12/07/mean-io初探/">2015-12-07</a></time>
<h1 class="title"><a href="/2015/12/07/mean-io初探/">mean.io初探</a></h1>
</header>
<div class="entry">
<p>最近学习使用了mean架构的一个框架mean.io,在这里记录下学到的东西和遇到的问题,以备后用。</p>
<h2 id="mean-io_u7684_u5B89_u88C5"><a href="#mean-io_u7684_u5B89_u88C5" class="headerlink" title="mean.io的安装"></a>mean.io的安装</h2><p>在安装mean.io之前必须要安装:</p>
<ul>
<li>mongodb</li>
<li>git</li>
<li>gulp / grunt</li>
</ul>
<p>之后在npm中输入<br><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm <span class="operator"><span class="keyword">install</span> -<span class="keyword">g</span> mean-cil</span></span><br></pre></td></tr></table></figure></p>
<p>安装完成后就使用<br><figure class="highlight nginx"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="title">mean</span> init</span><br></pre></td></tr></table></figure></p>
<p>来创建mean.io应用,会被要求输入应用名,之后自动从mean.io的github上复制文件<br>复制完成出现这个 </p>
<p><img src="images/meanInit.PNG"><br>这里默认选择no,但是创建一个管理员用户会很方便,所以选择yes创建管理员用户<br>在此之前要先打开mongodb,否则会报错 </p>
<p><img src="images/mongodb.PNG"><br>完成之后进入目录使用 npm install 安装依赖。值得吐槽的是,要装的依赖真是多…… </p>
<p>全部安装完成后第一个mean.io应用就可以使用了,使用<br><figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">gulp</span><br></pre></td></tr></table></figure></p>
<p>启动应用,在浏览器中打开 localhost:3000 即可看到搭建的默认应用,并且由于使用了gulp,在相关文件发生改变时页面会自动重载刷新</p>
<h3 id="u9047_u5230_u7684_u95EE_u9898"><a href="#u9047_u5230_u7684_u95EE_u9898" class="headerlink" title="遇到的问题"></a>遇到的问题</h3><p>mean init 时提示 “Prerequisite not installed: git”<br>官方文档说应当把git的可执行文件路径添加进去,然而并不明白……<br>在 StackOverflow 上找到了不错的解决办法,就是把git重装一遍,在下图界面选择”Use Git from the Windows Command Prompt”即可 </p>
<p><img src="images/gitSetup.PNG"></p>
<h3 id="Tips"><a href="#Tips" class="headerlink" title="Tips"></a>Tips</h3><p>每次启动应用之前需要先启动mongodb,否则会报错</p>
<h2 id="mean-io_u7684_u6587_u4EF6_u7ED3_u6784"><a href="#mean-io_u7684_u6587_u4EF6_u7ED3_u6784" class="headerlink" title="mean.io的文件结构"></a>mean.io的文件结构</h2><p>主要关注应用目录下的packages文件夹<br>通常会有core和custom两个子文件夹<br>core文件夹中包含的是首页、文章编辑、用户登录注册和管理员界面等<br>custom可以理解为分页面,就像一个新闻页面会有一个首页和每个版块的新闻分页面一样<br>custom里面装的就是这些分页面,并且这些分页面会自动添加到首页的导航栏中 </p>
<h3 id="core_u7684_u6587_u4EF6_u7ED3_u6784"><a href="#core_u7684_u6587_u4EF6_u7ED3_u6784" class="headerlink" title="core的文件结构"></a>core的文件结构</h3><p><img src="images/core.PNG"></p>
<ul>
<li>admin是管理员界面 </li>
<li>article是文章编辑、发布、展示的界面 </li>
<li>system是首页</li>
<li>users是登录、注册、忘记密码等界面</li>
</ul>
<p>system的结构如下</p>
<p><img src="images/system.PNG"><br>其中public是客户端</p>
<ul>
<li>assets用于存放样式表和图片</li>
<li>cotroller是angular的控制器,如模块定义、事件监听等</li>
<li>routes是angular路由</li>
<li>views是html视图层</li>
</ul>
<p>server是服务器端</p>
<ul>
<li>controller是node控制器,如模板渲染等</li>
<li>routes是node路由</li>
<li>views使用的模板引擎不像是ejs,查了一下是Django?它是将页面head、foot和主体内容组装起来的关键,其中includes里面存放了页面的head(仅仅就是html结构中head的部分)和foot layouts中的default.html引用head、foot的相关文件将其组装起来,但是主体内容部分还没有渲染。<br>在views目录下还有一个index.html,引用了default.html,并且添加了对主体部分的渲染,这样出来的页面就是一个完整的页面了。</li>
</ul>
<h3 id="custom_u7684_u6587_u4EF6_u7ED3_u6784"><a href="#custom_u7684_u6587_u4EF6_u7ED3_u6784" class="headerlink" title="custom的文件结构"></a>custom的文件结构</h3><p>custom下默认已经有一个子页面 i18n 和另外两个文件夹。按理说这三个都应该是属于子页面被添加到导航栏,但是实际上只有 i18n 被添加了,另外两个并没有。这两个文件夹还不能被移除,否则会报错。i18n这个是样例,新创建的子页面都会和它一样,这个文件夹可以随意移除或是更改名称。</p>
<h2 id="mean-io_u7684_u4F7F_u7528"><a href="#mean-io_u7684_u4F7F_u7528" class="headerlink" title="mean.io的使用"></a>mean.io的使用</h2><h3 id="u521B_u5EFA_u81EA_u5DF1_u7684_u5B50_u9875_u9762_u5E94_u7528__28package_29"><a href="#u521B_u5EFA_u81EA_u5DF1_u7684_u5B50_u9875_u9762_u5E94_u7528__28package_29" class="headerlink" title="创建自己的子页面应用 (package)"></a>创建自己的子页面应用 (package)</h3><p>官方文档中称这样的子页面应用为package,创建自己的package可以通过<br><figure class="highlight actionscript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">mean <span class="package"><span class="keyword">package</span> <<span class="title">packageName</span>></span></span><br></pre></td></tr></table></figure></p>
<p>创建,这样会自动按照i18n的结构在custom文件夹底下新建一个以packageName 为命名的文件夹,重载之后就可以在导航栏看到package名被添加上去,当然内容和i18n是一样的,要使它符合要求就要修改相关文件。</p>
<p>先写到这里吧改天接上后面的内容继续。</p>
</div>
<footer>
<div class="clearfix"></div>
</footer>
</div>
</article>
<nav id="pagination">
<div class="clearfix"></div>
</nav></div></div>
<aside id="sidebar" class="alignright">
<div class="search">
<form action="//google.com/search" method="get" accept-charset="utf-8">
<input type="search" name="q" results="0" placeholder="搜索">
<input type="hidden" name="q" value="site:mosquito1994.github.io">
</form>
</div>
<div class="widget tag">
<h3 class="title">标签</h3>
<ul class="entry">
<li><a href="/tags/express/">express</a><small>2</small></li>
<li><a href="/tags/mean/">mean</a><small>1</small></li>
<li><a href="/tags/mean-io/">mean.io</a><small>1</small></li>
<li><a href="/tags/nodejs/">nodejs</a><small>2</small></li>
</ul>
</div>
</aside>
<div class="clearfix"></div>
</div>
<footer id="footer" class="inner"><div class="alignleft">
© 2015 mosquito
</div>
<div class="clearfix"></div></footer>
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<!-- lazyload -->
<script type="text/javascript" src="http://apps.bdimg.com/libs/jquery-lazyload/1.9.5/jquery.lazyload.min.js"></script>
<script type="text/javascript">
jQuery(function() {
jQuery("img").lazyload({
placeholder:"http://www.arao.me/loading.gif",
effect:"fadeIn"
});
});
</script>
<script src="/js/jquery.imagesloaded.min.js"></script>
<script src="/js/gallery.js"></script>
<link rel="stylesheet" href="/fancybox/jquery.fancybox.css" media="screen" type="text/css">
<script src="/fancybox/jquery.fancybox.pack.js"></script>
<script type="text/javascript">
(function($){
$('.fancybox').fancybox();
})(jQuery);
</script>
</body>
</html>