《30天学习30种新技术》-Day 15:Meteor —— 从零开始创建一个 Web 应用
目录:https://segmentfault.com/a/1190000000349384
原文: https://segmentfault.com/a/1190000000361440
到目前为止我们讨论了Bower、AngularJS、GruntJS和PhoneGap等JavaScript技术。今天是“30天学习30种新技术”挑战的第15天,我决定重返JavaScript,学习Meteor框架。虽然Meteor的文档相当好,但是它缺少为初学者准备的教程。我觉得教程的学习效果更好,因为教程可以帮助你快速上手一种技术。本文将介绍如何利用 Meteor 框架构建一个epoll应用。
Meteor是什么?
Meteor是新一代的开发即时web应用的开源框架,它能帮助你在最少的时间内完成开发。它的理念和AngularJS、BackboneJS等框架大不相同。当我们在backbone 和 angular 上工作时,客户端(Angular或Backbone)和REST后端通讯。我们可以用任何技术写 REST 后端,例如 Java、NodeJS、PHP。
Meteor使用DDP(分布式数据协议)在客户端和服务器间传送数据。客户端JavaScript开发者需要解决的首要问题是:向后端的数据库发起查询,发送数据到客户端,当数据库变动时,推送变动到客户端。DDP是解决这一问题的标准做法。
Meteor应用的后端基于Node和MongoDB。前端和后端的应用同时使用Meteor的API。未来开发者可以选择 MongoDB 之外的其他数据库。
为什么使用Meteor?
请阅读Meteor的七大原则。
应用案例
本文中我们将搭建一个 epoll 应用,该应用允许用户发布问题并投票。这个应用可以做到:
当用户访问
/
时,会看到一个问题列表。用户需要通过Twitter登录,以便投票或发布新问题。如下图所示,由于未登录,投票按钮不可用。
当用户点击
Sign in with Twitter
之后,他将授权 epoll 应用使用他的账号。授权成功之后,用户可以投票或发布新问题。
GitHub仓库
今天的示例应用的代码可以从GitHub取得。
安装Meteor
开始使用Meteor很容易。如果你使用Mac或Linux,只需输入如下命令:
curl https://install.meteor.com | /bin/sh
Windows用户请参阅文档
创建Meteor应用
创建Meteor应用很容易。安装之后,运行create
命令即可。
meteor create epoll
这将创建epoll目录,该目录下有一些模板文件。项目结构如下所示:
让我们解释下这个结构:
meteor文件夹下保存meteor特定的文件。
.gitignore
忽略存储MongoDB数据库文件和应用文件的local
文件夹。packages
指明本应用所需的包。你可以把它们看成是npm包。Meteor以包的形式提供功能。本文中会使用一些包。release
保存了meteor版本。本文使用的版本是0.6.6.3
。epoll.css
决定应用的CSS样式。epoll.html
是应用的HTML标记。目前meteor只支持handlebars模板引擎,不过未来可能支持其他模板引擎。epoll.js
是meteor应用的核心。epoll.js
同时部署在服务器段和客户端。这允许开发者一次编写、两端使用。meteor创建的epoll.js
模板如下所示:
if (Meteor.isClient) {Template.hello.greeting = function () { return "Welcome to epoll."; }; Template.hello.events({ 'click input' : function () { // template data, if any, is available in 'this' if (typeof console !== 'undefined') console.log("You pressed the button"); } }); } if (Meteor.isServer) { Meteor.startup(function () { // code to run on server at startup }); }
Meteor.isServer
和Meteor.isClient
区分了服务器端和客户端的代码。
meteor
命令可以运行应用:
cd epoll
meteor
可以通过 http://localhost:3000 访问应用。点击按钮后,在chrome developer tools中你可以看到You pressed the button.
信息。
修改epoll.js
的欢迎部分:
Template.hello.greeting = function () {return "The Missing Meteor Tutorial!!!"; };
变动会自动应用,页面也会自动刷新。
MongoDB在哪?
前面提到Meteor使用MongoDB来存储数据。当我们安装meteor的时候,它同时会下载最新版的MongoDB。我们可以看到,MongoDB安装在<user.home>/.meteor
目录。使用ps -ef
可以找到MongoDB的安装位置。
; ps -ef|grep mongo501 1704 1687 0 2:22PM ttys001 0:09.28 /Users/shekhargulati/.meteor/tools/0b2f28e18b/mongodb/bin/mongod --bind_ip 127.0.0.1 --smallfiles --nohttpinterface --port 3002 --dbpath /Users/shekhargulati/day15/epoll/.meteor/local/db
在我的机子上,MongoDB运行于3002端口,以避免和其他默认运行于27017端口的MongoDB冲突。
智能的Meteor包管理
前面提到Meteor以包的形式实现功能。这些包在浏览器和服务器上都能使用。运行以下命令可以得知Meteor支持的所有包:
meteor list
使用meteor add
和meteor remove
命令来添加删除包。
添加Twitter Bootstrap包
我们将使用Twitter Bootstrap作为用户界面的风格。
meteor add bootstrap
注意,Meteor包不一定是最新版。
添加Twitter授权包
在我们的应用中,用户需要首先通过Twitter授权才能投票或添加问题。Meteor提供了accounts-ui
包,可以为我们的应用添加登录组件:
meteor add accounts-ui
然后我们添加授权提供者。在这个应用中,我们使用Twitter,不过我们其实也可以使用facebook、github、google、weibo或meetup。
meteor add accounts-twitter
添加包之后,我们需要更新下epoll.html
,添加Twitter登录按钮:
<head><title>Epoll : Share your opinion online, anywhere, anytime</title> </head> <body> <div class="navbar navbar-static-top navbar-inverse"> <div class="navbar-inner"> <div class="container"> <a class="brand" href="/">Epoll</a> <ul class="nav pull-right"> <li> {{loginButtons}} </li> </ul> </div> </div> </div> <div class="container" id="main"> {{> banner}} </div> </body> <template name="banner"> <div class="container"> <div class="row"> <div class="span6"> <div class="well"> <h4>Sign in using Twitter to submit new questions or to vote on existing questions.</h4> {{loginButtons}} </div> </div> </div> </div> </template>
然后调整一下样式,增加下面的代码到epoll.css
:
/* CSS declarations go here */
.login-display-name{color: white } .login-button{background-color: white} #main { padding-top:20px; }
应用会自动更新,你会见到这样的页面:
现在点击Configure Twitter Login
,会要求我们输入 twitter 应用的相关信息:
按照提示配置之后,我们可以使用twitter登录了。
授权之后我们可以登录应用。使用完毕之后,我们可以登出。
MongoDB会在用户集合内创建新用户。我们可以使用mongo
命令连接数据库查看:
; ~/.meteor/tools/0b2f28e18b/mongodb/bin/mongo --port 3002 MongoDB shell version: 2.4.6 connecting to: 127.0.0.1:3002/test > show dbs local 0.03125GB meteor 0.0625GB > use meteor switched to db meteor > show collections meteor_accounts_loginServiceConfiguration system.indexes users > db.meteor_accounts_loginServiceConfiguration.find() { "service" : "twitter", "consumerKey" : "xxx", "secret" : "xxx", "_id" : "xxx" } > > > db.users.find().pretty() { "createdAt" : ISODate("2013-11-11T18:03:23.488Z"), "_id" : "xx", "services" : { "twitter" : { "id" : "66993334", "screenName" : "shekhargulati", "accessToken" : "xxx-xxx", "accessTokenSecret" : "xxx", "profile_image_url" : "http://pbs.twimg.com/profile_images/378800000254412405/e4adcf8fb7800c3e5f8141c561cb57e4_normal.jpeg", "profile_image_url_https" : "https://pbs.twimg.com/profile_images/378800000254412405/e4adcf8fb7800c3e5f8141c561cb57e4_normal.jpeg", "lang" : "en" }, "resume" : { "loginTokens" : [ { "token" : "xxx", "when" : ISODate("2013-11-11T18:03:23.489Z") } ] } }, "profile" : { "name" : "Shekhar Gulati" } } >
定义应用层次
Meteor创建的模板应用有一个问题,客户端和服务器段的epoll.js
代码是一样的。任何人的都可以使用浏览器的开发工具查看epoll.js
。
如果我们不想将服务器端的特有代码发送到客户端,我们可以使用client
和server
目录来分隔代码。
cd epoll
mkdir client server
在两个目录下分别创建epollclient.js
和epollserver.js
文件。
client/epollclient.js
内存放客户端代码:
Template.hello.greeting = function () {return "The Missing Meteor Tutorial!!!"; }; Template.hello.events({ 'click input' : function () { // template data, if any, is available in 'this' if (typeof console !== 'undefined') console.log("You pressed the button"); } });
服务器端代码存放在server/epollserver.js
:
Meteor.startup(function () {// code to run on server at startup});``` 然后删除`epoll.js`: ```sh rm -f epoll.js
移除insecure
包
每一个Meteor应用预装了insecure
包。这个应用让用户端可以在数据库上实施一切操作。对于原型开发这很有用,但是通常不适合生产环境。
meteor remove insecure
发布问题
现在我们添加一个功能,已登录的用户可以提交新问题。
<head><title>Epoll : Share your opinion online, anywhere, anytime</title> </head> <body> <div class="navbar navbar-static-top navbar-inverse"> <div class="navbar-inner"> <div class="container"> <a class="brand" href="/">Epoll</a> <ul class="nav pull-right"> <li> {{loginButtons}} </li> </ul> </div> </div> </div> <div class="container" id="main"> {{#if currentUser}} {{> addquestion}} {{/if}} {{#unless currentUser}} {{> banner}} {{/unless}} </div> </body> <template name="banner"> <div class="container"> <div class="row"> <div class="span6"> <div class="well"> <h4>Sign in using Twitter to submit new questions or to vote on existing questions.</h4> {{loginButtons}} </div> </div> </div> </div> </template> <template name="addquestion"> <textarea rows="3" class="input-xxlarge" name="questionText" id="questionText" placeholder="Add Your Question"></textarea> <br/> <input type="button" class="btn-info add-question" value="Add Question"/> </template>
仅当用户登录的时候才会渲染addQuestion
模板。如果用户登出,则不会见到添加新问题的文本框。
我们需要同时更新客户端和服务器端的代码以便实现这一功能。
在client/epollclient.js
中加入:
Template.addquestion.events({'click input.add-question' : function(event){ event.preventDefault(); var questionText = document.getElementById("questionText").value; Meteor.call("addQuestion",questionText,function(error , questionId){ console.log('added question with Id .. '+questionId); }); document.getElementById("questionText").value = ""; } });
以上代码中:
我们首先将点击
input
事件绑定到add-question
类。接着我们阻止默认的点击事件,从DOM中获取问题文本。
然后我们调用Meteor服务器的方法
addQuestion
。由服务器负责插入、更新、删除数据等有风险的操作。客户端看不到实现,也无法私自修改数据。
现在我们需要修改server/epollserver.js
。我们首先定义一个名为Questions的新集合。然后我们会操作这个集合。Meteor使用minimongo作为API接口。参阅Meteor.Collection.documentation查看minimongo支持的所有操作。
Questions = new Meteor.Collection("questions");Meteor.startup(function () { // code to run on server at startup }); Meteor.methods({ addQuestion : function(questionText){ console.log('Adding Question'); var questionId = Questions.insert({ 'questionText' : questionText, 'submittedOn': new Date(), 'submittedBy' : Meteor.userId() }); return questionId; } });
现在访问我们的应用然后提交一个新问题:
查看下MongoDB中的数据
> db.questions.find().pretty()
{"questionText" : "Is Sachin Tendulkar the greatest batsman of all time?","submittedOn" : ISODate("2013-11-11T18:23:02.541Z"),"submittedBy" : "Jnu6oXoAZ2um57rZ8", "_id" : "nhqvgDcZqgZgLdDB7" }
问题列表
我们接下来要实现的功能是问题列表。用户不需登录,就可以看到所有问题的列表。
在main div
中加入:
{{> questions}}
然后添加问题模板:
<template name="questions"><h2>All Questions</h2> {{#each items}} {{> question}} {{/each}} </template> <template name="question"> <div> <p class="lead"> {{questionText}} <a class="btn btn-small btn-success yes {{#unless currentUser}}disabled{{/unless}}" href="#"><i class="icon-thumbs-up"></i> Yes {{yes}}</a> <a class="btn btn-small btn-danger no {{#unless currentUser}}disabled{{/unless}}" href="#"><i class="icon-thumbs-down"></i> No {{no}}</a> </p> </div> </template>
注意我们使用了unless
来确保用户未登录的情况下应用disabled
css。
为了获取所有问题,我们需要在客户端使用Question集合来获取所有文本。在client/epollclient.js
添加如下代码:
Questions = new Meteor.Collection("questions");Template.questions.items = function(){ return Questions.find({},{sort:{'submittedOn':-1}}); };
实现投票功能
最后我们需要实现投票功能。我们上面已经在html文件中加入了相关的模板代码,下面我们在client/epollclient.js
加入如下代码:
Template.question.events({'click': function () { Session.set("selected_question", this._id); }, 'click a.yes' : function (event) { event.preventDefault(); if(Meteor.userId()){ var questionId = Session.get('selected_question'); console.log('updating yes count for questionId '+questionId); Meteor.call("incrementYesVotes",questionId); } }, 'click a.no': function(){ event.preventDefault(); if(Meteor.userId()){ var questionId = Session.get('selected_question'); console.log('updating no count for questionId '+questionId); Meteor.call("incrementNoVotes",questionId); } } });
上面的代码实现了:
绑定点击事件到问题模板。点击任意问题的时,在
session
中设置questionId。session提供了一个客户端的全局对象,你可以在里面存储任意的键值对。当用户点击Yes按钮时,我们会从
session
中取得选中的questionId
,然后在服务器端调用incrementYesVotes
方法。我们使用Meteor.userId()
来确保用户已经登录了。当用户点击No按钮时,我们在服务器端调用
incrementNoVotes
函数。
最后我们在server/epollserver.js
加入incrementYesVotes
和incrementNoVotes
函数。我们使用Meteor的集合更新功能来增加计数器。
incrementYesVotes : function(questionId){console.log(questionId); Questions.update(questionId,{$inc : {'yes':1}}); }, incrementNoVotes : function(questionId){ console.log(questionId); Questions.update(questionId,{$inc : {'no':1}}); }
这样每次用户点击yes或no按钮之后,计数器会更新。你可以访问 http://localhost:3000 试验一番。
部署Meteor应用
部署Meteor应用有很多种方法。我们可以在Meteor提供的测试服务器上部署,也可以部署到OpenShift。
如果你打算部署到OpenShift上,请参阅Ryan的这篇博客。
运行以下命令可以部署到Meteor测试服务器:
meteor deploy epoll
应用可以通过 http://epoll.meteor.com/ 访问。
今天就是这些了。欢迎继续反馈。
转载于:https://www.cnblogs.com/guo2001china/p/5320368.html
《30天学习30种新技术》-Day 15:Meteor —— 从零开始创建一个 Web 应用相关推荐
- Day 15:Meteor —— 从零开始创建一个 Web 应用
到目前为止我们讨论了Bower.AngularJS.GruntJS和PhoneGap等JavaScript技术.今天是"30天学习30种新技术"挑战的第15天,我决定重返JavaS ...
- 30 天学习 30 种新技术系列
编者注:我们发现了比较有趣的系列文章<30 天学习 30 种新技术>,准备翻译,一天一篇更新,年终礼包.以下是译文,英文标题表示还未翻译,附原文链接:中文标题表示已翻译,附译文链接. 更新 ...
- Servlet学习DAY_01:服务器概念/Web服务器的作用/ Servlet概念/ 如何关联和解除Tomcat/ 创建一个Web工程 /Servlet响应流程/ Get-Post /常见异常
Servlet 什么是服务器 服务器就是一台高性能电脑 电脑上安装了提供服务的软件就称为 xxx服务器 举例: 邮件服务器: 就是在电脑上安装了提供邮件收发服务的软件 ftp服务器: 就是在电脑上安装 ...
- Vue.js 学习笔记十二:Vue CLI 之创建一个项目
目录 创建一个项目 创建一个项目 运行以下命令来创建一个新项目: vue create vuecli-demo 你会被提示选取一个 preset.你可以选默认的包含了基本的 Babel + ESLin ...
- 学习OceanBase :如何在MySQL模式下创建一个用户?
本节主要介绍如何创建一个用户. 谁可以创建用户 数据库在运行过程中,往往需要创建不同的用户,并为用户赋予相应的权限,一般被授予 CREATE USER 权限的用户可以创建用户. 由于 CREATE U ...
- 使用IntelliJ IDEA 15和Maven创建Java Web项目
转自:https://blog.csdn.net/myarrow/article/details/50824793博文链接! 转载于:https://www.cnblogs.com/yadonglia ...
- 使用IntelliJ IDEA 15和Maven创建Java Web项目(转)
1. Maven简介 相对于传统的项目,Maven 下管理和构建的项目真的非常好用和简单,所以这里也强调下,尽量使用此类工具进行项目构建, 它可以管理项目的整个生命周期. 可以通过其命令做所有相关的工 ...
- 学习 iOS14 新特性,教你如何创建一个优秀的 App Clip
前言 App clip 是 App 应用程序的轻量级版本,可在用户需要的位置和时间提供某些功能.在 Xcode 中, App clip 是和你主应用程序共享代码和资源的附加 Target.App cl ...
- OpenGL学习笔记:使用深度缓冲(Depth Buffer)创建一个旋转的立方体
如果不使用深度缓冲,创建的立方体的某些本应被遮挡住的面被绘制在了这个立方体其他面之上.OpenGL是一个三角形一个三角形地来绘制你的立方体的,所以即便之前那里有东西它也会覆盖之前的像素.因为这个原因, ...
- 30岁零基础没学历学Python怎么样?30岁学习Python晚吗?
30岁零基础没学历学Python怎么样?30岁学习Python晚吗?任何时候开始都不晚.30岁开始学习Python听起来年纪有点大,大家认为编程上了年纪学习编程语言是一个劣势.想在三十岁的时候通过学习 ...
最新文章
- 吴恩达演讲直指AI落地三大挑战,并提出解决方案(附视频)
- 学习笔记Spark(八)—— Spark SQL应用(3)—— Spark DataSet基础操作
- SELECT的学习以及在socket中的应用
- Spring Boot -Shiro配置多Realm 1
- java random用法_JAVA面试题(1)
- Java笔记-使用jpa连接mysql数据库
- Bootstrap-组件-2
- 制作centos的启动盘
- ASP数据库连接方式大全
- Android中通过反射和getResource()得到id的方式去改变View的显示效果
- user_agent
- webstorm主题网址+使用方法
- win10u盘被写保护怎么解除_win10系统下u盘被写保护怎么解除_win10解除u盘写保护方法...
- Inrie(洪晓军)
- php 三色排序,三色旗排序问题 | 学步园
- Excel筛选两列重复的内容
- 国二c语言考试要点,全国计算机二级考试c语言考试要点
- 怎么文字转语音?两分钟让你学会三种方法
- 如何绕过CDN获取网站的真实IP?手把手教你
- 元胞自动机CA+生命游戏代码
热门文章
- c语言 牛逼代码,有c语言牛逼的神人吗
- 【2019杭电多校第一场1009=HDU6586】String(贪心+序列自动机)
- (转)Dinkelbach算法(01二分规划更优解法)
- Stm32——keil5项目创建步骤
- 决策树分箱-特征工程之数据离散化处理-基于python实现
- java log4j 多线程_针对log4j 1.2.15中的并发锁问题,到底是io瓶颈,还是锁竞争导致线程block?...
- colspan会影响内部单元格宽度失效_冷轧轧辊失效原因分析及改进措施
- c语言随机数加密,TC伪随机数加密解决方法
- 容器技术Docker K8s 50 容器镜像服务(ACR)详解-使用与实践
- 图数据库实战 AWS Neptune Gremlin CloudFormation