使用 MEAN 进行全栈开发基础篇——4、接着前面玩儿添加
添加一个新用户
在本节中,你将了解有关使用 Express 创建 API 端点,使用 Angular 构建表单,以及使用 Monk 在 Mongo 中存储内容的更多信息。
与上一节类似,但在本节中我们将从后端到前端的几个步骤中实现此功能。首先,我们将创建一个用于添加用户的 API 端点。我们将使用 Express 路由创建此端点并使用 Monk 在 Mongo 中存储用户信息。然后,我们将创建一个包含表单的新网页以添加新用户。我们使用 Angular 构建此页面。
Let’s get started.
1. 创建一个 API 端点
打开 routes->users.js,在现有的路由之后和 module.exports
之前添加这个新路由(记住,module.exports
应该是你模块的最后一行):
router.post('/', function(req, res) {var collection = db.get('users');collection.insert({// 这里应该是和之前的用户保持同样属性// 有姓名、年龄、性别name: req.body.name,age: req.body.age,gender: req.body.gender}, function(err, user) {if (err) throw err;res.json(user);});
});
这段代码应该相当熟悉。谈谈重要的部分。首先,注意使用 router.post
方法。在上一节中,我们使用了 router.get
方法来处理 HTTP GET 请求。这里,我们使用 HTTP POST,这是用于创建新对象的 REST 风格约定。
在路由处理程序中,首先我们获得对用户集合的引用,然后使用 insert
方法向 Mongo 新增内容。
此方法的第一个参数是具有三个属性的 Json 对象:name
,age
和 gender
。我们使用 req.body
从前端获取这些属性的值。
最后,在用于 插入(insert
)的回调方法中,如果我们没有得到任何错误,我们应使用响应(res
)的 json
方法返回一个 Json 对象表示新用户的信息。
2. 创建一个表单
好的,API 准备完毕。现在我们需要一个用于添加用户的表单。
在 public->partials 下创建一个名为 user-form.html
的新视图文件。在此视图中键入以下代码:
<h1>Add a User</h1><form><div><label>Name</label><input></input></div><div><label>Age</label><input type="number"></input></div><div><label>Gender</label><input></input></div><input type="button" value="Save"></input>
</form>
现在,我们需要告诉 Angular 在用户访问到 /add-user
时渲染这个视图。我们需要一个新的路由这么做。
打开 forusers.js
并更新路由配置代码,如下所示:
app.config(['$routeProvider', function($routeProvider) {$routeProvider.when('/', {templateUrl: 'partials/home.html',controller: 'HomeCtrl'})// 添加这一部分.when('/add-user', {templateUrl: 'partials/user-form.html'}).otherwise({redirectTo: '/'});
}]);
注意,这里没有设置控制器,因为我们现在还没有,我们将在下一步中这样做。
视图和路由准备就绪。最后,我们需要在我们的主页中添加一个 /add-user
的链接。打开 partials->home.html 并在 ul
上方添加一个新链接:
<p><a href="/#!/add-user">Add a User</a>
</p>
请注意,你应该在你的 Angular 应用程序中的链接前面加上 /#!
。这用于兼容不支持单页应用程序的旧版浏览器。
注:原教程和译文均为
/#
,现在多了一个感叹号。
让我们预览我们迄今为止做了什么。返回浏览器,然后刷新主页,你应该会看到添加用户的链接。点击链接并查看添加用户页面。
我不得不承认,这个表单看起来真的很鬼,它离一个真正的应用程序还很远。让我们给它加上一个漂亮的外观。
添加并使用 Bootstrap
我们将使用 Bootstrap 为我们的表单添加一点风格。如果你不熟悉 Bootstrap,你只需要知道它是一个前端框架,用于构建现代化和响应式的 Web 应用程序。在这一步中,我们将引用 Bootstrap CSS 文件并使用一些 Bootstrap 类来装饰我们的表单元素。
打开 views->layout.jade 文件,添加如下行在 head
中的 link
下:
link(rel="stylesheet", href="//cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css")
确保它与上一行具有相同的缩进级别。现在,回到 partials->user-form.html。添加下面的类到 HTML 元素中:
<h1>Add a User</h1><form><div class="form-group"><label>Name</label><input class="form-control"></input></div><div class="form-group"><label>Age</label><input class="form-control" type="number"></input></div><div class="form-group"><label>Gender</label><input class="form-control"></input></div><input class="btn btn-primary" type="button" value="Save"></input>
</form>
这些类是用于创建表单的标准 Bootstrap 类。有关如何使用 Bootstrap 创建现代化风格表单的更多信息,请参阅 Bootstrap 文档。
让我们回到浏览器并刷新页面。Emm…现在看起来好多了~
现在,这个表单没有操作行为。如果点击保存按钮是没有任何反应的。这也是我们接下来要实现的东西。
实现控制器
正如之前所说,在 MVC 框架中,控制器负责处理视图触发的事件。我们将创建一个 Angular 控制器来处理 Save 按钮的点击操作事件。
打开 forusers.js
并在文件末尾键入以下代码:
app.controller('AddUserCtrl', ['$scope', '$resource', '$location',function($scope, $resource, $location) {$scope.save = function() {var Users = $resource('/api/users');Users.save($scope.user, function() {$location.path('/');});};}
]);
这个控制器有三个依赖:$scope
作为控制器和视图之间的胶水,$resource
用于使用我们的 RESTful API,$location
用于改变浏览器地址栏中的 URL。这些都是内置的 Angular 服务。
在这个控制器的主体中,我们在 $scope
上定义了 save
方法。当用户单击保存按钮时将调用此方法。我们很快就会把这个方法链接到我们的视图。现在,让我们看看这个方法里面发生了什么。
首先,我们调用 $resource
方法传递我们的 API(/api/users
)地址。这将返回一个对象方法来使用 API。在上一节中,我们使用查询方法来获取所有用户。在这里,我们使用 save
方法将用户提交到我们的 API。
Users.save
方法有两个参数:提交的对象和回调函数。这将使用异步的方式调用。在回调中,我们使用 $location
将浏览器的地址更改为网站的根目录。它将向用户显示主页。
现在,打开 partials->user-form.html 并更改输入字段如下:
<h1>Add a User</h1><form><div class="form-group"><label>Name</label><input class="form-control" ng-model="user.name"></input></div><div class="form-group"><label>Age</label><input class="form-control" type="number" ng-model="user.age"></input></div><div class="form-group"><label>Gender</label><input class="form-control" ng-model="user.gender"></input></div><input class="btn btn-primary" type="button" value="Save"></input>
</form>
ng-model
属性是我们用于数据绑定的另一个指令。这样,我们告诉 Angular,任何时候我们的输入字段中的值被改变,它应该自动更新 $scope
被引用的属性。在第一个示例中,当标题文本框的值更改时,Angular 将自动在 $scope.user.title
中设置它。
接下来,更改按钮声明如下:
<input class="btn btn-primary" type="button" value="Save" ng-click="save()"></input>
ng-click
属性是我们用来处理 HTML 元素点击事件的另一个 Angular 指令。有了这个指令,我们告诉 Angular,如果用户点击这个按钮,它应该在 $scope
上执行 save
方法,这是我们在几分钟前定义的。
最后,在路由中注册这个新的控制器:
.when('/add-user', {templateUrl: 'partials/user-form.html',controller: 'AddUserCtrl'})
我们完成了。让我们测试一下应用程序。返回浏览器,填写表单并提交。你应该会在列表中看到一个新用户。
我们这个页面没有做任何数据校验,如果你什么都不输入直接点 Save,它会存入一条空数据。
让我们快速回顾一下在本节中学到的内容。我们使用 Express 创建了一个新的 API 端点,并使用 Monk 在 Mongo 中存储用户信息。然后,我们创建了一个带有表单的 Angular 视图来添加用户,我们使用 Bootstrap 美化了表单。最后,我们为此视图创建了控制器来处理点击事件。在点击事件的处理程序中,我们使用 $resource
服务将数据提交到服务器。
在下一部分中,我们将学习修改现有用户信息的功能。
使用 MEAN 进行全栈开发基础篇——4、接着前面玩儿添加相关推荐
- 使用 MEAN 进行全栈开发基础篇——2、弄一个简单的用户管理试试
搭建项目 这下我们应该来搭建一个项目了,随便起个名字 ForUsers 找一个合适的位置,然后打开命令行:express ForUsers 会得如下树状图的结构 ├── app.js ├── bin ...
- Web全栈开发基础(小白入门版本)
博客传送门 近几个月认真写了写Web全栈代码,有点小收获这里分享一下.我还做了个PPT,资源路径 欢迎拍砖指点! Web全栈开发是一个听起来很虎的名词.本文从技术层面解释全栈开发,能帮助没有全栈概念, ...
- Python 全栈开发 -- 监控篇
如果你已经玩转了 Python 编程语言语法,肯定想用这些知识,开发一款应用程序,它可以是在网上,可以炫耀或出售,那就需要全栈式开发 Python.具体如何创建,部署和运行生产 Python Web ...
- python 仪表盘监控_Python 全栈开发 -- 监控篇
如果你已经玩转了 Python 编程语言语法,肯定想用这些知识,开发一款应用程序,它可以是在网上,可以炫耀或出售,那就需要全栈式开发 Python.具体如何创建,部署和运行生产 Python Web ...
- python全栈开发基础【第十七篇】面向对象反射和内置方法
一.静态方法(staticmethod)和类方法(classmethod) 类方法:有个默认参数cls,并且可以直接用类名去调用,可以与类属性交互(也就是可以使用类属性) 静态方法:让类里的方法直接被 ...
- python全栈开发基础【第二十三篇】线程
一.什么是线程 线程:顾名思义,就是一条流水线工作的过程,一条流水线必须属于一个车间,一个车间的工作过程是一个进程 所以,进程只是用来把资源集中到一起(进程只是一个资源单位,或者说资源集合),而线程才 ...
- python进程通信方式有几种_python全栈开发基础【第二十一篇】互斥锁以及进程之间的三种通信方式(IPC)以及生产者个消费者模型...
一.互斥锁 进程之间数据隔离,但是共享一套文件系统,因而可以通过文件来实现进程直接的通信,但问题是必须自己加锁处理. 注意:加锁的目的是为了保证多个进程修改同一块数据时,同一时间只能有一个修改,即串行 ...
- DevOps 全栈开发基础
VS Code 编辑器配置 推荐的插件 ESLint: 代码规范 Prettier: 代码美化 EditorConfig for VSCode: 配置编辑器空格.换行符等规则 Conventional ...
- python全栈开发基础【补充】包的补充
1.包A和包B下有同名模块也不会冲突,因为A.a与B.a来自俩个命名空间 2.常见目录结构 # 创建目录代码 import os os.makedirs('glance/api') os.makedi ...
最新文章
- POJ2455 Secret Milking Machine【二分,最大流】
- 在vs2005中安装boost库
- linux 下安装java
- 商业逻辑12讲之战略管理的逻辑
- java编写斐波那契数列,实战案例
- 浅谈LockSupport工具类
- jQuery缓存操作-cache数据
- Messages.exe (Win32.BMW.l.100640) 病毒的处理方法
- 单片机查表实验c语言,单片机 查表程序设计实验
- matlab:蚁群算法原理的实现
- multicast msdp 1
- 向传奇致敬,向约翰·纳什和他的妻子艾丽西亚致敬,缔造了数学和爱的传奇
- java剑姬_Java虚拟机非常有用的性能监控工具
- 正则表达式语法简介说明
- 中国帆船行业现状分析及发展前景展望报告2022-2028年
- 【日语】【歌词】「ヤキモチ」--高橋優
- 手机分辨率PPI和DPI的区别
- Win10任务栏透明工具TranslucentTB(TranslucentTB基础配置)
- vs2005无法附加,绑定句柄无效
- 信息收集域名、IP、端口服务、指纹识别相关信息
热门文章
- 与上海天文台关于坐标转换的约定
- Emmet 食用指北
- 堡垒之夜 服务器显示离线,堡垒之夜怎么是离线状态 | 手游网游页游攻略大全...
- 技校计算机专业自我鉴定,关于技校计算机专业的自我鉴定
- java开发实战经典(第二版)P528 14-1
- 使用keras-bert进行中文文本分类+Google colab运行源码
- JVM如何识别“到底谁才是垃圾“?
- 武侠小说中绝顶高手生存指南
- 计算机应用技术教程计应吗,计算机应用技术教程
- Windows用户密码的加密方法与破解