如果你有成为全栈的梦想,METEOR是个不错的平台。
1.创建你的第一个App(Creating your first app)
在这个教程中,我们会创建一个简单的App去管理待办事项列表并和他人合作完成任务。在完成这个项目后,你会对Meteor和它的项目结构有个基本的了解,。我们先创建App,打开命令行,键入以下命令:
译者注:前提是你安装了meteor,具体安装步骤可以参考这里
|
|
它会创建一个名叫simple-todos
的文件夹,里面包含我们开发meteor App所需要的文件:
|
|
运行这个新创建的App:
|
|
打开你的浏览器并输入http://localhost:3000
查看App是否运行成功。
在我们教程正式开始之前,你可以看看这个App的内部组成。比如,用你惯用的编辑器修改client/main.html
文件中的<h1>
内的文字。当你修改完毕保存文件时,浏览器会自动更新并展示新的内容,我们叫它热拔插(hot code push)
。
ES2015特性
如果你还没有尝试过下个版本的JavaScript特性,初始App内的代码语法,还有整个教程使用的语法,都会让你感到怪异。这是因为Meteor支持大部分ES2015的特性,也就是下个版本的JavaScript。常用的特性包括:
箭头函数:
(arg) => {return result;}
简写方法:
render() { ... }
const
和let
取代var
你可以在ecmascript docs查看Meteor支持的新特性。更多关于ES2015的信息可以查看下面几篇文章:
现在你有一些如何开发Meteor App的经验了,让我们开始创建一个待办事项列表应用程序吧!如果你在这个教程中发现了bug或是错误,可以在GitHub上请发起issue
或PR
。
2.使用React Components定义视图层(Defining views with React components)
我们把React作为视图层,让我们增加一些NPM packages,以便使用React进行开发。打开一个新的terminal在你的App根目录下,键入以下命令:
|
|
替换初始化的代码
在开始前,我们要替换App的初始代码。接下来我们讨论要做些什么。
第一步,替换初始化的HTML中的内容:
|
|
第二步,删除client/main.js
,并创建三个新文件:
|
|
|
|
|
|
我们仅在我们的App中做了3件事:
一个
App
React component一个
Task
React component一些初始化代码(在
client/main.jsx
客户端JavaScript入口文件中),在Meteor.startup
代码块中,我们知道当页面加载完毕后会执行里面的代码。这段代码加载其他组件,并渲染#render-target
元素。
你还可以在Application Structure article中了解import是如何工作的,还有如何组织你的代码。
在接下来的教程中,我们增加或更改代码,都会涉及到这些组件。
检查结果
在浏览器中,我们的app应该看起来像这个样子:
Todo List
This is task 1
This is task 2
This is task 3
如果你的app看起来不是这样,可以去GitHub下载代码,并和你自己的代码对比,找出不同的地方。
HTML文件定义静态内容
Meteor会解析你app目录下的所有HTML文件,并识别三个顶级标签<head>
,<body>
和<template>
。<head>
标签内的所有内容会发送到客户端HTML的head
标签,<body>
标签内的所有内容也会发送到客户端HTML的body
标签内,就和正常的HTML文件一样。
任何<template>
标签内的内容会编译成Meteor Templates,你可以在HTML中用{{>templateName}}
去调用,或在JavaScript中用Template.templateName
去调用。在这个教程中,我们不会用到Meteor提供的模板特性,因为我们将用React去定义所有视图组件。
用React定义视图组件
在React中,视图组件是React.Component
的子类(当我们用import { Component } from 'react'
的方式引入时)。你可以自由的在组件上添加方法,但有几个特殊的方法是不行的,比如render
方法。组件通过其父组件的props
属性,也可以接收数据。在这个教程中,我们会重温一些React的通用特性。你也可以查看React官方教程。
重新审视JSX中的render方法
在每个React Component中最重要的方法就是render()
,它会访问React并得到被描述的HTML,然后把组件显示出来。这个HTML内容用JavaScript扩展语法写成,叫JSX
,看起来就像在JavaScript中写HTML。你可以看到一些显而易见的差异:在JSX中,你要用className
去代替class
属性。还有一件很重要的事,它不是像Spacebars和Angular一样的模板语言,实际上它是直接编译成正常的JavaScript。查看更多JSX的信息。
JSX支持ecmascript
扩展包,所以它默认支持所有Meteor app的扩展包。
|
|
增加上面的CSS代码到你的项目中,这个首页看起来会很棒。在你的浏览器中检查样式是否加载进去了。
3.在集合中储存任务(Storing tasks in a collection)
Meteor使用集合(collections)储存持久化数据。在Meteor中,集合的特殊之处在于,可以同时在服务端和客户端读取数据,这让我们很容易编写视图层逻辑,而不需要编写太多服务端代码。集合会自动更新自身,所以一个视图组件配合集合,可以自动的显示最新的数据。
你可以在Meteor教程中阅读更多有关集合的文章。
创建一个集合很简单,只需要在你的代码中调用MyCollection = new Mongo.Collection("my-collection");
。在服务端,这会创建一个名叫my-collection
的MongoDB集合,它会创建一个缓存去链接服务端的集合。我们将在第12章节了解更多客户端和服务端的区别,我们假设整个数据库都运行在客户端,并开始编写我们的代码。
我们创建一个Mongo集合来定义新的tasks
模块,并导出它:
|
|
注意,我们把这个文件放在了新的目录imports/api
下。这是一个合适的位置,用于放置和API有关的文件。我们在这里抛出”collections”,之后读取它并添加一个”publications”,再用”methods”去编辑它。你可以在Meteor指南中了解更多有关如何在APP中组织你的代码结构。
我们需要在服务端导入这个模块(这将创建MongoDB集合,并设置管道得到数据给Client):
|
|
在React component中使用集合数据
我们使用Atmosphere包:react-meteor-data
,它会创建一个数据容器,把Meteor的响应式数据供给给React component。
我们要安装一个Meteor包,以及它要使用到的NPM包,react-addons-pure-render-mixin
:
|
|
在使用react-meteor-data
前,我们需要使用createContainer
高阶组件把我们的组件包裹在一个容器中:
|
|
这个被包裹的App
组件从Tasks
集合中提取tasks,并将它们用作App底层组件,它们被包装为tasks
prop。它以响应的方式运行,当数据库内容改变,App会重新渲染,我们可以立刻看到!
当你对代码进行以上更改时,你会发现之前在代办列表中的任务消失了。因为我们现在的数据库是空的,我们需要插入一些任务。
从服务端数据库控制台插入任务
我们称集合中的每一项为文档。使用服务端数据库控制台插入一些文档到我们的集合中。在一个新的terminal中进入你的app项目目录,并键入:
|
|
这会在你app的本地开发数据库中打开一个控制台。键入下面的代码:
|
|
在浏览器中,你可以立刻看到用户界面更新并展示了这个新的任务。可以看到,我们不需要编写任何代码将服务端数据库连接到前端——一切都是自动的。
用同样的方法从数据库控制台添加一些不同的任务吧。在下一章节,我们将了解怎样在app用户界面增加一些功能,比如不使用数据库控制台去增加任务。
4.使用表单添加任务
在这一章节,我们将增加一个表单字段,给用户在列表中添加任务。
首先,让我们增加一个表单域到App
组件中:
|
|
提示:JSX中添加注释的方法:{/* … */}
你可以看到form
元素有一个onSubmit
属性,它映射到组件的handleSubmit
方法。在React中,你可以这样监听浏览器事件,就像表单上的submit事件。input
元素有一个ref
属性,它能让我们稍后轻松的访问到这个元素。
让我们添加handleSubmit
放到到App
组件里:
|
|
现在你的App有一个新的表单字段了。只需要在输入框输入文本,并按下回车键,就可以添加任务了。如果你打开一个新的浏览器窗口并再打开这个app,你会发现列表会自动自动在所有客户端同步。
在React中监听事件
就如你看到的,你可以通过参考组件上切确的方法来管理DOM事件。在事件管理器内部,你可以通过使用React.findDOMNode
去拿到带有ref
属性的元素。查看更多React支持的事件类型,以及事件系统如何运行的,请参考React文档。
插入集合
在事件管理器内部,我们通过调用Tasks.insert
添加了一个任务到tasks
集合,因为我们不用为集合定义一个模式,所以可以添加任何属性到任务对象,比如创建时间。
客户端可以添加任何数据到数据库,这样并不安全,但目前来说一切都没问题。在第10章节,我们将学习怎样安全并有限制的将数据插入到数据库中。
储存我们的任务
目前,我们最新的任务在列表的最底下。这对任务列表来说不是很好,我们希望看到最新的任务在最前面。
我们可以通过使用createdAt
字段自动排序来解决此问题。只需在包裹App
组件的数据容器内的find
方法调用时添加一个排序选项:
|
|
回到浏览器,并确认是否如期运行:任何新添加的任务都会出现在列表的最顶端,而不是底部。
在下一章节,我们会增加一些十分重要的待办事项列表特性:检查任务和删除任务。
5.检查任务和删除任务
到目前为止,我们还仅仅只能插入文档。现在,我们将学习怎么去更新和删除它们。
让我们添加两个新元素到我们的组件,一个复选框和一个删除按钮,以及它们对应的时间管理器:
|
|
更新
在上面代码中,我们调用Tasks.update
去检查一个任务。
集合上的更新功能需要两个参数。第一个参数是标识集合子集的选择器,第二个是一个update参数,用来指定要对匹配对象做什么。
在这个例子中,选择器就是相对应的任务的_id
,update参数用$set
去切换checked
字段,这将代表任务是否已经完成。
删除
上面代码使用Tasks.remove
去删除任务。remove
函数只需要一个参数,一个选择器,用于确定要在集合中删除的项目。
6.在Android或iOS上运行app
目前,Meteor并不支持在Windows上进行移动端打包。如果你是Windows用户,请忽略这一章节。
目前为止,我们构建了我们的app,并在浏览器上对它进行测试,但是Meteor是为了跨平台而设计的——只需要几句命令,就可以把你的待办事项列表网站构建成Android或iOS应用。
Meteor可以轻松的设置所有构建app所需的工具,但是下载所有程序可能需要一段时间——Android大约300M,iOS要安装Xcode大约2GB,如果你不希望下载这些工具,你可以调到下一个章节。
在iOS模拟器上运行
如果你有Mac,你可以运行在iOS模拟器上运行app。
进入到app目录并键入:
|
|
它会安装你构建iOS app所要用到的所有所有配置。当上面安装完成,键入:
|
|
你会看到iOS模拟器弹出,并且你的app在里面运行。
在Android模拟器上运行
在terminal中进入你的app目录并键入:
|
|
它会安装你构建Android app所要用到的所有所有配置。当上面安装完成,键入:
|
|
同意协议条款,键入:
|
|
在一些初始化后,我们将看到一个Android模拟器弹出,你的app在原生生Android容器里运行。
模拟器运行可能会有一些慢,所以如果你想看到应用真实的情况,还得到真实设备上使用。
在Android设备上运行
首先,完成上述的所有Android设置步骤。然后,确定你的设备有USB调试模式而且手机插进了电脑的USB插口。此外,你必须在真机运行前关闭安卓模拟器。
接下来,键入以下命令:
|
|
你的app将会构建并安装到你的设备上。
在iPhone或iPad上运行(只限Mac:要有苹果开发者账号)
如果你有苹果开发者账号,你也可以在iOS设备上运行你的app。键入以下命令:
|
|
这将会为你的iOS app项目打开Xcode。你可以使用Xcode让app运行在任何Xcode支持的设备或模拟器上。
现在我们看到了在移动端运行我们的app多么容易,让我们给app再添加一些特性。
7.在组件状态中存储临时的用户界面数据
在这一章节,我们将在app中添加客户端数据过滤功能,以便用户选择只查看未完成的任务。我们将学习怎样使用React的component state去存储只在客户端用到的临时数据。
首先,我们需要增加一个复选框到App
组件:
|
|
你可以看到它从this.state.hideCompleted
读取数据。React有一个特殊的字段叫state
,你可以把组件数据存储和封装在里面。我们需要在组件的构造器中初始化this.state.hideCompleted
的值:
|
|
我们可以事件管理器中调用this.setState
去更新this.state
,这将异步更新state属性,并重新渲染组件:
|
|
当this.state.hideCompleted
为true时,我们需要更新renderTasks
方法去过滤已经完成的任务:
|
|
如果你现在选择复选框,任务列表不会再展现已经完成的任务了。
新的特性:显示未完成任务的数目
现在我们要写一个查询条件,用来过滤掉已经完成的任务。我们也可以用相同的查询来显示已完成的任务总数。为此,我们需要在我们的数据容器中拿到一个计数,并在render
方法中添加一行代码。因为我们已经有客户端集合中的数据,增加这个额外的计数不需要向服务端发起任何请求。
|
|
|
|
8.添加账户
Meteor自带一个账户系统和用户登录接口,让你在短短几分钟就能添加多用户功能到你的app内。
目前,Meteor使用Blaze UI组件作为它的默认UI引擎。在未来,也可能会有专为React定制的组件。
开启账户系统和UI,我们需要增加相对应的包。在你的app目录,运行以下命令:
|
|
在React中写Blaze组件
要通过accounts-ui
包使用Blaze UI,我们需要把它包裹在React组件中。这样让我们在新文件中创建了一个叫AccountsUIWrapper
的新组件:
|
|
在App中定义刚刚创建的组件:
|
|
接下来,增加下列代码去配置accounts UI,用username去替换email address:
|
|
同时我们需要在客户端入口导入这个配置文件:
|
|
添加用户相关功能
本文作者:余震(Freak)
本文出处:Rockjins Blog
版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC-SA 3.0 CN许可协议。转载请注明出处!