├── .bowerrc
├── .gitignore
├── LICENSE
├── README.md
├── app.js
├── bin
└── www
├── bower.json
├── package.json
├── public
├── application.js
├── example
│ ├── controllers
│ │ └── example.client.controller.js
│ ├── example.client.module.js
│ ├── services
│ │ └── example.client.service.js
│ └── views
│ │ └── example.client.view.html
├── stylesheets
│ └── style.css
└── user
│ ├── controllers
│ └── user.client.controller.js
│ ├── services
│ └── user.client.service.js
│ ├── user.client.module.js
│ └── views
│ └── user.client.view.html
├── routes
├── index.js
└── users.js
└── views
├── error.ejs
└── index.ejs
/.bowerrc:
--------------------------------------------------------------------------------
1 | {
2 | "directory": "public/lib"
3 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea/
2 |
3 | # Logs
4 | logs
5 | *.log
6 |
7 | # Runtime data
8 | pids
9 | *.pid
10 | *.seed
11 |
12 | # Directory for instrumented libs generated by jscoverage/JSCover
13 | lib-cov
14 |
15 | # Coverage directory used by tools like istanbul
16 | coverage
17 |
18 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
19 | .grunt
20 |
21 | # node-waf configuration
22 | .lock-wscript
23 |
24 | # Compiled binary addons (http://nodejs.org/api/addons.html)
25 | build/Release
26 |
27 | # Dependency directory
28 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
29 | node_modules
30 | public/lib
31 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 lwdz
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | AngularJS简易入门
2 | ======
3 |
4 | ## 介绍AngularJS
5 |
6 | * AngularJS是JavaScript前端框架
7 | * 使用MVC架构创建单页应用
8 |
9 | > AngularJS是Google开发的纯客户端JavaScript技术的WEB框架,用于扩展、增强HTML功能,它专为构建强大的WEB应用而设计。
10 |
11 | ## AngularJS的关键概念
12 |
13 | ### AngularJS核心模块
14 |
15 | 包含一些对象和实体,用来完成AngularJS应用的基本操作
16 |
17 | ### angular全局对象
18 |
19 | ```angular``` 全局对象包含一些可以用来创建和启动应用的方法。```angular``` 对象包含了一个精简版的```jQuery``` ,叫做```jqLite``` 。可以使得Angular做一些简单的DOM操作。
20 |
21 | ### AngularJS 模块
22 |
23 | 在AngularJS中,一切都被封装在模块之中。AngularJS需要至少一个模块来进行操作。
24 |
25 | #### 应用模块
26 |
27 | AngularJS需要至少一个模块来启动,这个模块就是应用模块。
28 | 使用```angular.module(name, [requires], [configFn])```来创建和获取模块。
29 |
30 | * ```name```: 模块的名字
31 | * ```requires```: 模块的依赖
32 | * ```configFN```: 模块注册时调用的方法
33 |
34 | 传入一个参数,获取对应模块。传入多个参数进行创建。(类似重载,跟是jQuery的setter,getter类似)
35 |
36 | #### 附加模块
37 |
38 | 同样是AngularJS team开发的,但是不包含在核心功能里的模块。
39 |
40 | #### 第三方模块
41 |
42 | 由其他人开发的模块
43 |
44 | ### 双向数据绑定
45 | 双向数据绑定,使AngularJS应用总是保持model和view的一致。
46 |
47 | > 单向数据绑定与双向数据绑定
48 |
49 | ### 依赖注入
50 |
51 | 示例:使用module的controller方法创建一个controller
52 |
53 | ```javascript
54 | angular.module('someModule').controller('SomeController',
55 | function($scope){
56 | ...
57 | });
58 | ```
59 |
60 | controller方法接收了两个参数,一个是controller的名字,另一个是controller的构造方法。构造方法中被注入了一个AngularJS的对象:$scope。
61 | AngularJS通过方法的参数的名字来进行注入。
62 | 当进行压缩(混淆)的时候,会变成
63 |
64 | ```javascript
65 | angular.module('someModule').controller('SomeController',
66 | function(a){
67 | ...
68 | });
69 | ```
70 |
71 | 这样AngularJS就懵逼了。
72 | 通常采用“注释数组”的方式进行注入
73 |
74 | ```javascript
75 | angular.module('someModule').controller('SomeController', ['$scope',
76 | function($scope) {
77 | ...
78 | }]);
79 | ```
80 | ###AngularJS指令
81 | AngularJS就是一些标记,一般是属性或者元素名。从根本上讲,AngularJS是通过指令与DOM元素进行交互的。
82 | ####核心指令
83 | AngularJS自带了一些必要的指令。
84 | 最基本的指令:ng-app 一般写在页面的body或者html标签上。
85 |
86 | ```html
87 |
88 | ```
89 | * ng-controller: 指定哪个contoller来管理这块元素视图
90 | * ng-model: 绑定个哪个值
91 | * ng-show/ng-hide: 根据布尔表达式决定是否显示
92 | * ng-repeat: 迭代数组,重复html元素
93 |
94 | > [查看更多](http://docs.angularjs.org/api/)
95 |
96 | ####自定义指令
97 | 自己写指令,可以根据元素或者属性来修改已有的DOM元素。
98 |
99 | ####启动一个Angluar应用
100 | 启动,或者说引导一个AngularJS应用,就是说告诉Angular在哪个DOM元素是根元素以及何时来初始化Angular应用。
101 | #####自动启动
102 | 使用ng-app指令,当应用的JavaScript文件加载完成时,AngularJS就会找ng-app所在的元素。ng-app可以没有值,也可有一个名字。
103 | 如果有一个名字,则必须创建这个module。
104 | #####手动启动
105 | 需要用到以下方法
106 |
107 | ```javascript
108 | angular. bootstrap(element, [modules], [config])
109 | ```
110 |
111 | * element: 想要启动的DOM元素
112 | * modules: 启动的模块
113 | * config: 启动的配置
114 |
115 | 方法在jqLite的document-ready事件中进行调用。
116 |
117 | ##安装AngularJS
118 |
119 | * 使用CDN文件
120 | * 下载后使用自己服务器提供
121 |
122 | ###使用bower管理依赖
123 | ```shell
124 | $ npm install -g bower
125 | ```
126 | 创建bower.json指定依赖
127 |
128 | ```javascript
129 | {
130 | "name": "MEAN",
131 | "version": "0.0.1",
132 | "dependencies": { }
133 | }
134 | ```
135 |
136 | ###配置bower依赖管理
137 | 创建.bowerrc文件指定依赖下载的路径
138 |
139 | ```javascript
140 | {
141 | "directory": "public/lib"
142 | }
143 | ```
144 | ###使用Bower安装AngularJS
145 | ```javascript
146 | {
147 | "name": "MEAN",
148 | "version": "0.0.1",
149 | "dependencies": {
150 | "angular": "~1.2"
151 | }
152 | }
153 | ```
154 |
155 | ```shell
156 | $ bower install
157 | ```
158 |
159 | ###配置AngluarJS
160 |
161 | ```html
162 |
163 |
164 |
165 | <%= title %>
166 |
167 |
168 |
169 | <%= title %>
170 | Welcome to <%= title %>
171 |
172 |
173 |
174 | ```
175 | > git checkout -f v1
176 |
177 | ##AngularJS应用结构
178 |
179 | * 水平结构
180 | * 垂直结构
181 | * 垂直结构改良(示例采用此种)
182 |
183 | ##启动(引导)AngularJS应用
184 | 我们采用手动启动的方式。
185 | 比自动启动更加灵活,更加容易控制,然后而并没有什么卵用。
186 | public 目录中创建application.js
187 |
188 | ```javascript
189 | var mainApplicationModuleName = 'mean';
190 | var mainApplicationModule = angular.module(mainApplicationModuleName, []);
191 | angular.element(document).ready(function() {
192 | angular.bootstrap(document, [mainApplicationModuleName]);
193 | });
194 | ```
195 | 在index.ejs中引入application.js
196 |
197 | ```html
198 |
202 |
203 |
204 | ```
205 | 启动服务,查看效果。(双向数据绑定)
206 | > git checkout -f v3 (忘写v2了)
207 |
208 | ##AngularJS MVC
209 | MVC design pattern
210 | 在public文件中,新建一个名为example的模块文件夹。在example中再建两个子文件夹controllers,views
211 | 在example中新建一个文件example.client.module.js
212 | public/example/example.client.module.js中写入以下代码
213 |
214 | ```javascript
215 | angular.module('example', []);
216 | ```
217 | 在index.ejs中引入
218 |
219 | ```html
220 |
221 | ```
222 | 通过依赖注入方式将example模块加入到主应用模块中
223 |
224 | ```javascript
225 | var mainApplicationModule = angular.module(mainApplicationModuleName, ['example']);
226 | ```
227 | > git checkout -f v4
228 |
229 | ###AngularJS views
230 | example.client.view.html --> public/example/views
231 |
232 | ```html
233 |
237 | ```
238 |
239 | index.ejs中
240 |
241 | ```html
242 |
243 | ```
244 |
245 | ###AngularJS controllers and scopes
246 |
247 | * scope是连接controller和view的一个对象
248 | * dom层级的关系,所以scope也是有层级的关系.本scope找不到的对象,会向上去查找。
249 | * 一般使用ng-controller来指定view的controller(也可以在路由配置中指定模controller)
250 |
251 | ```javascript
252 | example.client.controller.js --> public/example/controllers
253 | angular.module('example').controller('ExampleController', ['$scope',
254 | function($scope) {
255 | $scope.name = 'MEAN Application';
256 | }
257 | ]);
258 | ```
259 | index.ejs引入
260 | ```html
261 |
262 | ```
263 |
264 | ```html
265 | example.client.view.html
266 |
267 |
271 | ```
272 | > git checkout -f v5
273 |
274 | ##AngularJS路由
275 |
276 | AngularJS主要用于“单页应用”,ngRoute管理整个浏览器中的路由。AngularJS将加载定义的模板,把结果写入DOM,服务器只是用来提供静态文件的加载,不对url变化做响应。这样就使的服务器更像一个“面向API”的后端。(好处:移动应用流行,原生应用可以和网页应用共用同一套API)
277 | ###安装ngRoute模块
278 |
279 | ```javascript
280 | {
281 | "name": "MEAN",
282 | "version": "0.0.1",
283 | "dependencies": {
284 | "angular": "~1.2",
285 | "angular-route": "~1.2"
286 | }
287 | }
288 | ```
289 | ```shell
290 | $ bower install
291 | ```
292 | index.ejs中引入
293 |
294 | ```html
295 |
296 | ```
297 | application.js注入
298 |
299 | ```javascript
300 | var mainApplicationModule = angular.module(mainApplicationModuleName, ['ngRoute', 'example']);
301 | ```
302 |
303 | ###配置 URL
304 | 使用url的hash部分来进行路由,hash部分变化,不向服务器发送请求。(锚点)
305 | (缺点:单页应用不用利于搜索引擎的抓取和SEO。解决:搜索引擎给开发者提供一个标记,来标记应用为单页应用,Hashbangs)
306 | AngluarJS的$locationProvider服务支持这种配置
307 | public/application.js
308 |
309 | ```javascript
310 | mainApplicationModule.config(['$locationProvider',
311 | function($locationProvider) {
312 | $locationProvider.hashPrefix('!');
313 | }
314 | ]);
315 | ```
316 | 这样搜索引擎就会等待AJAX的请求,来获得网页内容。
317 |
318 | ###AngluarJS应用路由
319 |
320 | 使用ngRoute中的$routeProvider对象,这个对象提供了一些方法来定义路由行为。在一个模块中注入$routeProvider对象来进行配置。
321 |
322 | ```javascript
323 | example.client.routes.js --> public/example
324 | angular.module('example').config(['$routeProvider',
325 | function($routeProvider) {
326 | $routeProvider.when('/', {
327 | templateUrl: 'example/views/example.client.view.html'
328 | }).otherwise({
329 | redirectTo: '/'
330 | });
331 | }
332 | ]);
333 | ```
334 | 使用angular.module()获得example这个模块,然后使用config方法,注入$routeProvider对象,进行配置。when(),otherwise()
335 |
336 | 除了$routeProvider,另一个打包在ngRoute中的是ng-view,ng-view就是告诉DOM元素,在哪里显示路由视图。
337 |
338 | ```html
339 | app/views/index.ejs
340 |
341 |
342 | 引入
343 |
344 | ```
345 | > git checkout -f v6
346 |
347 |
348 | ##AngularJS服务
349 |
350 | 单例实体,用于在不同实体中共享信息。可以用来从服务中获取数据,共享缓存数据,注入全局对象等。
351 |
352 | ###AngularJS自带的一些服务
353 |
354 | * $http: 用来处理AJAX请求
355 |
356 | ```
357 | // Simple GET request example :
358 | $http.get('/someUrl').
359 | success(function(data, status, headers, config) {
360 | // this callback will be called asynchronously
361 | // when the response is available
362 | }).
363 | error(function(data, status, headers, config) {
364 | // called asynchronously if an error occurs
365 | // or server returns response with an error status.
366 | });
367 |
368 | // Simple POST request example (passing data) :
369 | $http.post('/someUrl', {msg:'hello word!'}).
370 | success(function(data, status, headers, config) {
371 | // this callback will be called asynchronously
372 | // when the response is available
373 | }).
374 | error(function(data, status, headers, config) {
375 | // called asynchronously if an error occurs
376 | // or server returns response with an error status.
377 | });
378 | ```
379 |
380 | * $resource: 用来处理RESTful APIs,支持一系列的方法和参数。
381 | 需要安装angular-resource.js,添加ngResource依赖
382 |
383 | ```
384 | 默认的动作
385 | { 'get': {method:'GET'},
386 | 'save': {method:'POST'},
387 | 'query': {method:'GET', isArray:true},
388 | 'remove': {method:'DELETE'},
389 | 'delete': {method:'DELETE'} };
390 | 也可以加入自定动作
391 | ```
392 |
393 | * $location: 用来操作url
394 | * $q: 用来操作promises
395 | * $rootScope: 返回rootScope
396 | * $window: 返回浏览器window对象
397 |
398 | ###创建AngluarJS服务
399 | 一般使用两种方法来创建:
400 |
401 | ```
402 | //使用service提供数据的返回
403 | angular.module('example').factory('ExampleService', [
404 | function() {
405 | return true;
406 | }
407 | ]);
408 |
409 | //通过service方法实例化一个单例对象,注意使用了prototype的方式
410 | angular.module('example').service('ExampleService', [
411 | function () {
412 | this.someValue = true;
413 | this.hello = 'world';
414 | this.firstMethod = function () {
415 | };
416 | this.secondMethod = function () {
417 | };
418 | }
419 | ]);
420 | ```
421 | ###使用服务
422 |
423 | 同样是通过注入的方式
424 |
425 | ```
426 | 创建services文件夹 --> example.client.service.js文件
427 | ```
428 |
429 | index.ejs引入
430 |
431 | ```
432 |
433 | ```
434 |
435 | example.client.controller.js中注入
436 |
437 | ```
438 | angular.module('example').controller('ExampleController', ['$scope', 'ExampleService',
439 | function($scope, ExampleService) {
440 | $scope.name = 'MEAN Application';
441 | $scope.test = ExampleService.hello;
442 | }
443 | ]);
444 | ```
445 | view中加入显示
446 |
447 | ```
448 | hello {{test}}!!
449 | ```
450 |
451 | > git checkout -f v7
452 | >
453 | > git checkout -f v8 增加user模块
454 | >
455 | > git checkout -f v9 user模块使用service与服务器进行交互
456 |
--------------------------------------------------------------------------------
/app.js:
--------------------------------------------------------------------------------
1 | var express = require('express');
2 | var path = require('path');
3 | var favicon = require('serve-favicon');
4 | var logger = require('morgan');
5 | var cookieParser = require('cookie-parser');
6 | var bodyParser = require('body-parser');
7 |
8 | var routes = require('./routes/index');
9 | var users = require('./routes/users');
10 |
11 | var app = express();
12 |
13 | // view engine setup
14 | app.set('views', path.join(__dirname, 'views'));
15 | app.set('view engine', 'ejs');
16 |
17 | // uncomment after placing your favicon in /public
18 | //app.use(favicon(__dirname + '/public/favicon.ico'));
19 | app.use(logger('dev'));
20 | app.use(bodyParser.json());
21 | app.use(bodyParser.urlencoded({ extended: false }));
22 | app.use(cookieParser());
23 | app.use(express.static(path.join(__dirname, 'public')));
24 |
25 | app.use('/', routes);
26 | app.use('/users', users);
27 |
28 | // catch 404 and forward to error handler
29 | app.use(function(req, res, next) {
30 | var err = new Error('Not Found');
31 | err.status = 404;
32 | next(err);
33 | });
34 |
35 | // error handlers
36 |
37 | // development error handler
38 | // will print stacktrace
39 | if (app.get('env') === 'development') {
40 | app.use(function(err, req, res, next) {
41 | res.status(err.status || 500);
42 | res.render('error', {
43 | message: err.message,
44 | error: err
45 | });
46 | });
47 | }
48 |
49 | // production error handler
50 | // no stacktraces leaked to user
51 | app.use(function(err, req, res, next) {
52 | res.status(err.status || 500);
53 | res.render('error', {
54 | message: err.message,
55 | error: {}
56 | });
57 | });
58 |
59 |
60 | module.exports = app;
61 |
--------------------------------------------------------------------------------
/bin/www:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | /**
4 | * Module dependencies.
5 | */
6 |
7 | var app = require('../app');
8 | var debug = require('debug')('angluar:server');
9 | var http = require('http');
10 |
11 | /**
12 | * Get port from environment and store in Express.
13 | */
14 |
15 | var port = normalizePort(process.env.PORT || '3000');
16 | app.set('port', port);
17 |
18 | /**
19 | * Create HTTP server.
20 | */
21 |
22 | var server = http.createServer(app);
23 |
24 | /**
25 | * Listen on provided port, on all network interfaces.
26 | */
27 |
28 | server.listen(port);
29 | server.on('error', onError);
30 | server.on('listening', onListening);
31 |
32 | /**
33 | * Normalize a port into a number, string, or false.
34 | */
35 |
36 | function normalizePort(val) {
37 | var port = parseInt(val, 10);
38 |
39 | if (isNaN(port)) {
40 | // named pipe
41 | return val;
42 | }
43 |
44 | if (port >= 0) {
45 | // port number
46 | return port;
47 | }
48 |
49 | return false;
50 | }
51 |
52 | /**
53 | * Event listener for HTTP server "error" event.
54 | */
55 |
56 | function onError(error) {
57 | if (error.syscall !== 'listen') {
58 | throw error;
59 | }
60 |
61 | var bind = typeof port === 'string'
62 | ? 'Pipe ' + port
63 | : 'Port ' + port;
64 |
65 | // handle specific listen errors with friendly messages
66 | switch (error.code) {
67 | case 'EACCES':
68 | console.error(bind + ' requires elevated privileges');
69 | process.exit(1);
70 | break;
71 | case 'EADDRINUSE':
72 | console.error(bind + ' is already in use');
73 | process.exit(1);
74 | break;
75 | default:
76 | throw error;
77 | }
78 | }
79 |
80 | /**
81 | * Event listener for HTTP server "listening" event.
82 | */
83 |
84 | function onListening() {
85 | var addr = server.address();
86 | var bind = typeof addr === 'string'
87 | ? 'pipe ' + addr
88 | : 'port ' + addr.port;
89 | debug('Listening on ' + bind);
90 | }
91 |
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "MEAN",
3 | "version": "0.0.1",
4 | "dependencies": {
5 | "angular": "~1.2",
6 | "angular-route": "~1.2",
7 | "angular-resource": "~1.2"
8 | }
9 | }
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angluar",
3 | "version": "0.0.0",
4 | "private": true,
5 | "scripts": {
6 | "start": "node ./bin/www"
7 | },
8 | "dependencies": {
9 | "body-parser": "~1.12.4",
10 | "cookie-parser": "~1.3.5",
11 | "debug": "~2.2.0",
12 | "ejs": "~2.3.1",
13 | "express": "~4.12.4",
14 | "morgan": "~1.5.3",
15 | "serve-favicon": "~2.2.1",
16 | "underscore": "^1.8.3"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/public/application.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by li on 15/6/3.
3 | */
4 | var mainApplicationModuleName = 'mean';
5 | var mainApplicationModule = angular.module(mainApplicationModuleName, ['ngRoute', 'ngResource', 'example', 'user']);
6 |
7 | mainApplicationModule.config(['$locationProvider',
8 | function ($locationProvider) {
9 | $locationProvider.hashPrefix('!');
10 | }
11 | ]);
12 |
13 | mainApplicationModule.config(['$routeProvider',
14 | function ($routeProvider) {
15 | $routeProvider.when('/', {
16 | templateUrl: 'example/views/example.client.view.html'
17 | }).when('/user', {
18 | templateUrl: 'user/views/user.client.view.html',
19 | controller: 'UserController'
20 | }).otherwise({
21 | redirectTo: '/'
22 | });
23 | }
24 | ]);
25 |
26 | angular.element(document).ready(function () {
27 | angular.bootstrap(document, [mainApplicationModuleName]);
28 | });
--------------------------------------------------------------------------------
/public/example/controllers/example.client.controller.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by li on 15/6/3.
3 | */
4 | angular.module('example').controller('ExampleController', ['$scope', 'ExampleService',
5 | function($scope, ExampleService) {
6 | $scope.name = 'MEAN Application';
7 |
8 | $scope.test = ExampleService.hello;
9 | }
10 | ]);
--------------------------------------------------------------------------------
/public/example/example.client.module.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by li on 15/6/3.
3 | */
4 | angular.module('example', []);
--------------------------------------------------------------------------------
/public/example/services/example.client.service.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by li on 15/6/3.
3 | */
4 | angular.module('example').service('ExampleService', [
5 | function () {
6 | this.someValue = true;
7 | this.hello = 'world';
8 | this.firstMethod = function () {
9 | };
10 | this.secondMethod = function () {
11 | };
12 | }
13 | ]);
--------------------------------------------------------------------------------
/public/example/views/example.client.view.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/stylesheets/style.css:
--------------------------------------------------------------------------------
1 | body {
2 | padding: 50px;
3 | font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;
4 | }
5 |
6 | a {
7 | color: #00B7FF;
8 | }
--------------------------------------------------------------------------------
/public/user/controllers/user.client.controller.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by li on 15/6/4.
3 | */
4 | angular.module('user').controller('UserController', ['$scope', 'UserService',
5 | function ($scope, UserService) {
6 | $scope.users = UserService.query();//query是$resource的一个默认动作
7 |
8 | $scope.add = function () {
9 | var user = {name: $scope.user.name, age: $scope.user.age};
10 | UserService.add(user, function (response) {
11 | $scope.users.push(user);
12 | }, function (response) {
13 | alert('fail');
14 | });
15 | };
16 |
17 | //失败之后才和服务器同步,使页面响应更快。(看起来)
18 | $scope.del = function (name, index) {
19 | $scope.users.splice(index, 1)
20 | UserService.remove({name: name}, function (response) {
21 |
22 | }, function (response) {
23 | $scope.users = UserService.query();
24 | });
25 | };
26 |
27 | //添加完成之后重新获取,可以使页面中和服务器保持一致。
28 | $scope.update = function () {
29 | UserService.update({name: 'li', age: 16}, function (response) {
30 | $scope.users = UserService.query();
31 | }, function (response) {
32 | alert('fail');
33 | });
34 | }
35 |
36 | }
37 | ]);
--------------------------------------------------------------------------------
/public/user/services/user.client.service.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by li on 15/6/4.
3 | */
4 | angular.module('user').factory('UserService', ['$resource',
5 | function ($resource) {
6 | return $resource('/users/:name', {name: '@name'}, {
7 | update: {method: 'PUT'},
8 | add: {method: 'POST', params: {name: ''}}
9 | });
10 | }
11 | ]);
--------------------------------------------------------------------------------
/public/user/user.client.module.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by li on 15/6/4.
3 | */
4 | angular.module('user', []);
--------------------------------------------------------------------------------
/public/user/views/user.client.view.html:
--------------------------------------------------------------------------------
1 |
2 | - {{$index + 1}}: {{user.name}}, {{user.age}}
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/routes/index.js:
--------------------------------------------------------------------------------
1 | var express = require('express');
2 | var router = express.Router();
3 |
4 | /* GET home page. */
5 | router.get('/', function(req, res, next) {
6 | res.render('index', { title: 'Angular' });
7 | });
8 |
9 | module.exports = router;
10 |
--------------------------------------------------------------------------------
/routes/users.js:
--------------------------------------------------------------------------------
1 | var express = require('express');
2 | var router = express.Router();
3 | var _ = require('underscore');
4 |
5 | var users = [
6 | {name: 'li', age: 18},
7 | {name: 'wang', age: 38},
8 | {name: 'liu', age: 27}
9 | ];
10 |
11 | router.get('/', function (req, res, next) {
12 | res.json(users);
13 | });
14 |
15 | router.post('/', function (req, res, next) {
16 | var user = req.body;
17 | users.push(user);
18 | res.send(user);
19 | });
20 |
21 | router.put('/:userId', function (req, res, next) {
22 |
23 | var name = req.params.userId;
24 | var age = req.body.age;
25 |
26 | _.each(users, function (e) {
27 | if (e.name === name) {
28 | e.age = age;
29 | }
30 | });
31 |
32 | res.end();
33 | });
34 |
35 | router.delete('/:userId', function (req, res, next) {
36 |
37 | var name = req.params.userId;
38 |
39 | users = _.reject(users, function (e) {
40 | return e.name === name;
41 | });
42 |
43 | res.end();
44 | });
45 | module.exports = router;
46 |
--------------------------------------------------------------------------------
/views/error.ejs:
--------------------------------------------------------------------------------
1 | <%= message %>
2 | <%= error.status %>
3 | <%= error.stack %>
4 |
--------------------------------------------------------------------------------
/views/index.ejs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | <%= title %>
5 |
6 |
7 |
8 | <%= title %>
9 | Welcome to <%= title %>
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------