如何构建和结构一个Node.js MVC应用程序

詹姆斯Kolce尼尔森雅克
分享

在一个重要的应用程序中,架构和代码本身的质量一样重要。我们可以有编写良好的代码段,但如果我们没有良好的组织,随着复杂性的增加,我们将会遇到困难。没有必要等到项目完成了一半才开始考虑架构;最好的时间是在开始之前,把我们的目标作为我们选择的灯塔。

Node.js不像Ruby有Rails框架那样有一个事实上的框架,它对架构和代码组织没有强烈的意见。因此,很难开始使用Node构建完整的web应用程序。

在本教程中,我们将使用MVC架构构建笔记应用程序的基本功能。为了实现这一点,我们将使用Hapi.js框架node . js而且SQLite作为数据库,使用Sequelize.js,加上其他小型公用事业,以加快我们的发展。我们将使用哈巴狗模板语言。

什么是MVC?

模型-视图-控制器(或MVC)可能是最流行的应用程序架构之一。和其他很多人一样计算机历史上很酷的事情时,MVC模型被构思出来帕洛阿尔托研究中心为Smalltalk语言提供了一种解决方案,可以用图形用户界面组织应用程序。它是为桌面应用程序创建的,但从那以后,这个想法已经适应了包括Web在内的其他媒介。

我们可以用简单的术语来描述MVC架构:

  • 模型:应用程序中处理数据库或任何数据相关功能的部分。
  • 视图:用户将看到的所有内容——基本上就是我们要发送给客户端的页面。
  • 控制器:我们网站的逻辑,以及模型和视图之间的粘合剂。在这里,我们调用模型来获取数据,然后我们把数据放在视图上,发送给用户。

我们的应用程序将允许我们创建、查看、编辑和删除纯文本笔记。它不会有其他功能,但因为我们已经定义了一个坚实的体系结构,所以以后添加东西时不会有很多麻烦。

本教程假设您的计算机上安装了Node的最新版本。如果不是这样,请咨询我们的关于安装和运行Node的教程

您可以查看最终的应用程序附带的GitHub存储库,这样您就可以大致了解应用程序的结构。

打好基础

构建任何Node.js应用程序的第一步是创建一个package.json文件,它将包含我们所有的依赖项和脚本。而不是手动创建这个文件,npm可以使用初始化命令:

mkdirnotes-boardcdnotes-boardnpminit - y

流程完成后,我们会有一个package.json文件准备使用。

注意:如果您不熟悉这些命令,请检查我们的npm初学者指南

我们将继续安装Hapi.js -本教程选择的框架。它在简单性、稳定性和功能之间提供了很好的平衡,这些功能将很好地适用于我们的用例(尽管还有其他选项也可以很好地工作)。

npm安装@hapi / hapi@18.4.0

这个命令将下载Hapi.js并将其添加到我们的package.json文件作为依赖项。

注意:我们已经指定了Hapi.js的v18.4.0版本,因为它与Node版本8、10和12兼容。如果使用Node 12,可以选择安装最新版本(Hapi v19.1.0)。

现在我们可以创建我们的入口文件- web服务器将启动一切。继续创建一个server.js文件在你的应用程序目录,并添加以下代码:

“使用严格的”常量哈皮神=需要“@hapi /哈皮神”常量设置=需要”。/设置”常量初始化=异步= >常量服务器=哈皮神服务器港口设置港口服务器路线方法“获得”路径“/”处理程序请求h= >返回“你好,世界!”等待服务器开始控制台日志服务器运行在:$ {服务器信息uri过程“unhandledRejection”犯错= >控制台日志犯错过程退出1初始化

这将是我们应用程序的基础。

首先,我们表明我们将使用严格模式,这是一个常见的做法当使用hadoop .js框架时。

接下来,我们将包含依赖项并实例化一个新的服务器对象,我们将连接端口设置为该对象3000(端口可以是任意数字大于1023,小于65535).

我们的服务器的第一个路由将作为一个测试来检查是否一切正常,所以一个“Hello, world!”这句话对我们来说就足够了。在每个路由中,我们必须定义它将响应的HTTP方法和路径(URL),以及处理程序(处理HTTP请求的函数)。handler函数可以接受两个参数:请求而且h.第一个包含关于HTTP调用的信息,第二个将为我们提供处理对该调用的响应的方法。

最后,我们使用server.start ()方法。

存储我们的设置

将配置变量存储在专用文件中是一个很好的实践。这个文件导出了一个包含数据的JSON对象,其中每个键都是从一个环境变量分配的——但没有忘记一个回退值。

在这个文件中,我们还可以根据我们的环境(比如开发环境或生产环境)进行不同的设置。例如,出于开发目的,我们可以在内存中使用SQLite实例,但在生产中使用真正的SQLite数据库文件。

根据当前环境选择设置非常简单。因为我们还有一个env变量,该变量将包含其中之一发展生产,我们可以像下面这样做来获取数据库设置:

常量dbSettings=设置设置envdb

所以dbSettings将包含内存中数据库的设置时env变量是发展时,或将包含数据库文件的路径env变量是生产

此外,我们还可以添加对.env文件,我们可以在本地存储环境变量以用于开发目的。这是使用包来完成的dotenvfor Node.js,它将读取一个.env文件,并自动将找到的值添加到环境中。

注意:如果你决定也用一个.env文件,确保您安装包NPM安装dotenv然后添加到.gitignore所以你不会发布任何敏感信息。

我们的settings.js文件看起来是这样的:

//这将加载我们的.env文件,并将值添加到process.env,//重要:如果你不想使用这个功能,省略这一行需要“dotenv”配置沉默真正的模块出口=港口过程env港口||3000env过程envNODE_ENV||“发展”//环境相关设置发展db方言“sqlite”存储”:记忆:“生产db方言“sqlite”存储“db / database.sqlite”

现在,我们可以通过执行以下命令并导航到来启动应用程序http://localhost:3000在我们的网页浏览器中:

节点server.js

注意:该项目在Node v12.15.0上进行测试。如果您得到任何错误,请确保您已经更新了安装。

定义路由

路由的定义为我们提供了应用程序所支持的功能的概述。为了创建额外的路由,我们只需要复制已经在我们的server.js文件,改变每一个内容。

让我们首先创建一个名为自由在我们的项目中。这里我们将包括所有的JS组件。

内部自由,让我们创建一个routes.js文件并添加以下内容:

“使用严格的”常量路径=需要“路径”模块出口=//我们将在这里定义我们的路由

在这个文件中,我们将导出一个对象数组,其中包含应用程序的每个路由。要定义第一条路由,将以下对象添加到数组中:

方法“获得”路径“/”处理程序请求h= >返回“所有的笔记都会出现在这里”配置描述“获取所有可用的笔记”

我们的第一个路径是主页(/),因为它只返回信息,所以我们给它赋值a得到方法。现在,它只会给我们“所有的注释将出现在这里”的消息,稍后我们将为控制器函数更改该消息。的描述配置节仅用于文档目的。

的下面,为笔记创建四种路径/注意/路径。因为我们要建立一个CRUD应用程序,我们需要为每个操作提供一个路由HTTP方法

在前面的路由后面增加如下定义:

方法“职位”路径“/注意”处理程序请求h= >返回“新笔记”配置描述"添加新注释"方法“获得”路径“/注意/{蛞蝓}”处理程序请求h= >返回“这是一张纸条”配置描述“获取笔记的内容”方法“把”路径“/注意/{蛞蝓}”处理程序请求h= >返回“编辑笔记”配置描述"更新所选笔记"方法“获得”路径“/注意/{蛞蝓}/删除”处理程序请求h= >返回"这张纸条已经不存在了"配置描述"删除所选笔记"

我们所做的与前面的路由定义相同,但这一次我们更改了方法以匹配我们想要执行的操作。

唯一的例外是删除路由。在本例中,我们将用得到方法而不是删除再加一个/删除在路上。这样,我们只需访问相应的URL就可以调用删除操作。

注意:如果计划实现严格的REST接口,则必须使用删除方法,并删除/删除路径的一部分。

我们可以用花括号将单词括起来来命名路径中的参数。因为我们要通过音段来识别音符,我们添加{蛞蝓}的路径除外帖子路线;我们不需要它,因为我们不会与特定的音符交互,而是创建一个音符。

你可以在官方文档

现在,我们必须将新路线添加到server.js文件。让我们在文件的顶部导入路由文件:

常量路线=需要”。/ lib /路线”

然后让我们将当前的测试路线替换为以下内容:

服务器路线路线

构建模型

模型允许我们定义数据的结构以及使用它的所有功能。

在这个例子中,我们将使用SQLite数据库Sequelize.js,这将为我们提供一个更好的界面,使用ORM (对象关系映射)技术。它还将为我们提供一个与数据库无关的接口。

建立数据库

SQLite和Sequelize的安装命令如下:

npm安装sequelize sqlite3

现在创建一个模型目录里面lib /文件名为index.js,它将包含数据库和Sequelize.js设置,并包括以下内容:

“使用严格的”常量Fs=需要“fs”常量路径=需要“路径”常量Sequelize=需要“sequelize”常量设置=需要“. . / . . /设置”常量dbSettings=设置设置envdb常量sequelize=SequelizedbSettings数据库dbSettings用户dbSettings密码dbSettings常量db=FsreaddirSync__dirname过滤器文件= >文件indexOf“。”= = !0& &文件= = !“index.js”forEach文件= >常量模型=sequelize进口路径加入__dirname文件db模型的名字=模型dbsequelize=sequelizedbSequelize=Sequelize模块出口=db

首先,我们将包括将要使用的模块:

  • Fs,以读取内部的文件模型文件夹,它将包含所有的模型
  • 路径,以连接当前目录中每个文件的路径
  • Sequelize,这将允许我们创建一个新的Sequelize实例
  • 设置,其中包含我们的数据settings.js项目根目录下的文件

接下来,我们创建一个newsequelize变量,它将包含Sequelize实例,使用当前环境的数据库设置。我们要用sequelize导入所有的模型,并使它们在我们的db对象。

db对象将被导出,并将包含每个模型的数据库方法。当我们需要对数据做一些事情时,它将在我们的应用程序中可用。

加载所有的模型,而不是手动定义它们,我们在模型目录(除了index.js文件)并使用进口函数。返回的对象将为我们提供CRUD方法,然后将其添加到db对象。

最后,我们加sequelize而且Sequelize作为我们的一部分db对象。第一个将用于我们的server.js文件在启动服务器之前连接到数据库,如果您在其他文件中也需要它,则包括第二个文件以方便使用。

创建我们的笔记模型

在本节中,我们将使用Moment.js包来帮助设置日期格式。你可以使用以下命令安装它并将其作为依赖项包含:

npm安装时刻

我们要创建一个note.js文件内的模型目录,这将是我们应用程序中唯一的模型。它将提供我们所需要的所有功能。

将以下内容添加到该文件中:

“使用严格的”常量时刻=需要“时刻”模块出口=sequelize数据类型= >常量请注意=sequelize定义“注意”日期类型数据类型日期得到函数返回时刻getDataValue“日期”格式“MMMM Do, YYYY”标题数据类型字符串鼻涕虫数据类型字符串描述数据类型字符串内容数据类型字符串返回请注意

导出一个函数,该函数接受sequelize实例,以定义模型,以及数据类型对象中包含数据库中所有可用类型。

接下来,我们使用一个对象定义数据的结构,其中每个键对应于一个数据库列,键的值定义了我们要存储的数据类型。类型中的数据类型列表Sequelize.js文档.数据库中的表将根据这些信息自动创建。

对于date列,我们还定义了Sequelize应该如何返回值getter函数(得到密钥)。我们在返回信息之前指明这一点。它应该首先通过Moment实用程序以更易于阅读的方式进行格式化(MMMM Do, YYYY).

注意:虽然我们得到的是一个简单易读的日期字符串,但它被存储为JavaScript的精确日期字符串产品日期对象。所以这不是一个破坏性的操作。

最后,返回我们的模型。

同步数据库

现在,在应用程序中使用数据库之前,我们必须同步数据库。在server.js,导入文件顶部的模型:

//导入models目录下的index.js文件常量模型=需要”。/ lib /模型/”

接下来,删除以下代码块:

等待服务器开始控制台日志服务器运行在:$ {服务器信息uri

把它替换成这个:

等待模型sequelize同步等待服务器开始控制台日志服务器运行在:$ {服务器信息uri

这段代码将使模型与我们的数据库同步。完成此操作后,服务器将启动。

构建控制器

控制器是接受请求而且响应工具包对象。的请求对象包含有关所请求资源的信息,我们使用回复向客户端返回信息。

在我们的应用程序中,我们现在只返回一个JSON对象,但是我们将在构建视图后添加视图。

我们可以把控制器看作是连接模型和视图的函数;它们将与我们的模型通信以获取数据,然后在视图中返回该数据。

家庭控制器

我们将要构建的第一个控制器将处理站点的主页。创建一个home.js文件在lib /控制器目录,内容如下:

“使用严格的”常量模型=需要“. . /模型/”模块出口=异步请求h= >常量结果=等待模型请注意findAll订单“日期”“DESC”返回数据笔记结果页面“Home -便签板”描述“欢迎来到我的笔记板”

方法获取数据库中的所有音符findAll我们模型的方法。这个函数将返回一个Promise,如果它解决了,我们将得到一个包含数据库中所有notes的数组。

方法将结果按降序排列订单对象中的参数findAll方法,因此最后一项将首先出现。中的所有可用选项Sequelize.js文档

一旦我们有了家庭控制器,我们可以编辑我们的routes.js文件。首先,我们在文件顶部导入模块,位于路径模块导入:

常量首页=需要”。/控制器/家”

然后我们将刚刚创建的控制器添加到数组中:

方法“获得”路径“/”处理程序首页配置描述“获取所有可用的笔记”

您可以通过重新启动服务器(节点server.js)及参观http://localhost:3000/.您应该看到以下响应:

“数据”“笔记”“页面”“Home -便签板”“描述”“欢迎来到我的笔记板”

注释控制器的样板

因为我们要用一个蛞蝓来识别我们的音符,所以我们可以使用音符的标题和鼻涕虫库,所以让我们安装它,并使用以下命令将其作为依赖项包含:

npm安装鼻涕虫

我们必须在应用程序中定义的最后一个控制器将允许我们创建、读取、更新和删除注释。

我们可以继续创建note.js文件内的lib /控制器目录并添加以下内容:

“使用严格的”常量请注意=需要“. . /模型/”常量Slugify=需要“鼻涕虫”常量路径=需要“路径”模块出口=//这里我们将在routes.js文件中包含处理剩余请求的函数。

创建函数

为了向数据库中添加注释,我们将编写一个创建函数将会包装创建方法中使用有效负载对象中包含的数据。

在导出的对象中添加以下内容:

创建异步请求h= >常量结果=等待请注意创建日期日期标题请求有效载荷noteTitle鼻涕虫Slugify请求有效载荷noteTitle较低的真正的描述请求有效载荷noteDescription内容请求有效载荷noteContent//生成一个带有'result'数据的新记录返回结果

创建了注释之后,我们将返回注释数据并将其作为JSON发送给客户端回复函数。

现在,我们只返回结果,但是一旦我们在下一节中构建了视图,我们就能够生成带有新注释的HTML,并在客户机上动态添加它。虽然这并不是完全必要的,并且取决于您如何处理前端逻辑,但我们将返回一个HTML块来简化客户机上的逻辑。

另外,请注意,日期是在执行函数时动态生成的,使用新的日期()

函数

要只搜索一个元素,可以使用findOne方法。既然我们通过音符的弦段来识别音符,那么在哪里过滤器必须在URL中包含客户端提供的段码(http://localhost: 3000 /注意:鼻涕虫:):

异步请求h= >常量请注意=等待请注意findOne在哪里鼻涕虫请求参数个数鼻涕虫返回请注意

与前面的函数一样,我们只返回结果,它将是一个包含note信息的对象。中构建视图后,视图将被使用构建视图部分。

更新函数

要更新注释,可以使用更新方法。它有两个对象——我们要替换的新值,以及包含a的选项在哪里使用注释段进行过滤,这是我们要更新的注释:

更新异步请求h= >常量=标题请求有效载荷noteTitle描述请求有效载荷noteDescription内容请求有效载荷noteContent常量选项=在哪里鼻涕虫请求参数个数鼻涕虫等待请注意更新选项常量结果=等待请注意findOne选项返回结果

在更新数据之后,由于数据库不会返回更新后的笔记,所以我们可以再次找到修改后的笔记并将其返回给客户端,这样我们就可以在更改完成后立即显示更新后的版本。

删除函数

删除控制器将通过向摧毁我们模型的函数。然后,一旦注释被删除,我们将重定向到主页。为了实现这一点,我们使用重定向Hapi响应工具包的功能:

删除异步请求h= >等待请注意摧毁在哪里鼻涕虫请求参数个数鼻涕虫返回h重定向“/”

在我们的路由中使用Note控制器

此时,我们应该准备好带有所有CRUD操作的笔记控制器文件。但是要使用它们,我们必须将它包含在我们的路由文件中。

的顶部导入控制器routes.js文件:

常量请注意=需要”。/控制器/注意”

我们必须用我们的新函数替换每个处理程序,所以我们应该有我们的路由文件如下:

方法“职位”路径“/注意”处理程序请注意创建配置描述"添加新注释"有效载荷多部分真正的方法“获得”路径“/注意/{蛞蝓}”处理程序请注意配置描述“获取笔记的内容”方法“把”路径“/注意/{蛞蝓}”处理程序请注意更新配置描述"更新所选笔记"有效载荷多部分真正的方法“获得”路径“/注意/{蛞蝓}/删除”处理程序请注意删除配置描述"删除所选笔记"

注意:我们包括我们的函数没有()最后,因为我们引用了函数而没有调用它们。

在Hapi v19中,request.payload.multipart改为默认情况下.我们得把它调回真正的帖子而且路径,我们会用到FormData对象将数据传输到服务器,并且传输的数据将在多部分/格式格式。

构建视图

此时,我们的站点正在接收HTTP调用并响应JSON对象。为了使它对每个人都有用,我们必须创建以良好的方式呈现信息的页面。

在这个例子中,我们将使用哈巴狗(以前是Jade)模板语言,尽管这不是强制性的,我们可以使用其他语言的Hapi.js。我们要用愿景插件在我们的服务器中启用视图功能。

注意:如果你不熟悉Jade/Pug,请参阅我们的哈巴狗初学者指南

可以使用以下命令安装软件包:

npm安装@hapi / vision@5.5.4哈巴狗

这里我们正在安装v5.5.4版本的vision插件,它与Hapi v18兼容。如果您选择安装Hapi v19,您可以简单地输入NPM I @hapi/vision获取最新版本。

Note组件

首先,我们将构建note组件,它将在视图之间重用。此外,我们将在一些控制器函数中使用该组件在后端动态地构建一个注释,以简化客户机上的逻辑。

lib /视图/组件被称为note.pug内容如下:

文章.contenth2.title一个href=/注意/$ {请注意鼻涕虫=请注意标题p.subtitle.is-6发布于#{note.date}p=请注意内容

它由笔记的标题、出版日期和笔记的内容组成。

基本布局

基本布局包含页面的常见元素——换句话说,对于我们的例子来说,包含所有非内容的元素。在lib /视图/被称为layout.pug内容如下:

doctype html字符集=“utf - 8”的名字=“视口”内容=的宽度=设备-宽度初始=1标题=页面的名字=“描述”内容=描述链接rel=“样式表”href=“https://cdn.jsdelivr.net/npm/bulma@0.8.0 / css / bulma.min.css”脚本推迟=src=“https://use.fontawesome.com/releases/v5.3.1/js/all.js”身体块的内容脚本src=“/脚本/ main.js”

其他页面的内容将被加载在块的内容.方法中显示一个页面变量标题元素,一个描述中的变量元(name =“描述”)元素。稍后我们将在路由中创建这些变量。

出于样式的目的,我们包括Bulma CSS框架而且字体太棒了来自CDN。我们还包括amain.js该文件将包含所有用于前端的自定义JavaScript代码。请现在创建该文件静态/公共/脚本/目录中。

Home View

在我们的主页上,我们将显示数据库中所有音符的列表和一个按钮,该按钮将显示一个带有允许我们通过Ajax创建新音符的表单的模态窗口。

lib /观点被称为home.pug内容如下:

延伸布局块的内容部分.section.containerh1.title.has-text-centered|笔记板.tabs.is-centeredul一个.show-modalhref=“#”发布主要容器.notes-list每一个请注意数据笔记包括组件/注意人力资源.modal.modal-background.modal-card.modal-card-headp.modal-card-title添加注按钮deletearia-label=“关闭”部分.modal-card-body形式行动=/注意的方法=“职位”.note-form# note-form.field范式输入.input的名字=“noteTitle”类型=“文本”占位符=“标题”.field范式输入.input的名字=“noteDescription”类型=“文本”占位符=的简短描述.field范式文本区域.textarea的名字=“noteContent”占位符=“内容”.field范式按钮.button.is-link保存

视图

笔记页面与主页非常相似,但在本例中,我们显示了一个菜单,其中包含特定于当前笔记的选项、笔记的内容以及与主页相同的表单,但是已经填充了当前笔记信息,因此当我们更新它时它就在那里。

lib /观点被称为note.pug内容如下:

延伸布局块的内容部分.section.containerh1.title.has-text-centered|笔记板.tabs.is-centeredul一个href=' / '首页一个.show-modalhref=“#”更新一个href=/注意/$ {请注意鼻涕虫/删除删除包括组件/注意.modal.modal-background.modal-card.modal-card-headp.modal-card-title编辑注意按钮deletearia-label=“关闭”部分.modal-card-body形式行动=/注意/$ {请注意鼻涕虫方法=“把”.note-form# note-form.field范式输入.input的名字=“noteTitle”类型=“文本”占位符=“标题”价值=请注意标题.field范式输入.input的名字=“noteDescription”类型=“文本”占位符=的简短描述价值=请注意描述.field范式文本区域.textarea的名字=“noteContent”占位符=“内容”# {note.content}.field范式按钮.button.is-link保存

客户端的JavaScript

为了创建和更新笔记,我们将使用一些JavaScript,既可以显示/隐藏带有表单的模态,也可以通过Ajax提交请求。虽然这不是必须的,但我们认为它为用户提供了更好的体验。

这就是我们的内容main.js静态/公共/脚本/目录:

/ /模态常量模态=文档querySelector“.modal”常量超文本标记语言=文档querySelector“html”常量showModal== >模态班级名册添加“活跃”超文本标记语言班级名册添加“夹”常量hideModal== >模态班级名册删除“活跃”超文本标记语言班级名册删除“夹”文档querySelector“a.show-modal”addEventListener“点击”函数eepreventDefaultshowModal模态querySelector".模态deleteaddEventListener“点击”函数eepreventDefaulthideModal//表单提交常量形式=文档querySelector“# note-form”常量url=形式getAttribute“行动”常量方法=形式getAttribute“方法”常量prependNote=超文本标记语言= >常量notesList=文档querySelector“.notes-list”常量div=文档createElement" div "divinnerHTML=超文本标记语言notesList方法div写上。notesList写上。常量updateNote=超文本标记语言= >常量文章=文档querySelector“文章”常量div=文档createElement" div "divinnerHTML=超文本标记语言文章parentNode方法的div写上。文章常量调用onSuccess=超文本标记语言= >hideModal形式重置如果方法= = =“职位”prependNote超文本标记语言其他的如果方法= = =“把”updateNote超文本标记语言形式addEventListener“提交”e= >epreventDefault获取url方法身体FormData形式然后响应= >响应文本然后文本= >调用onSuccess文本错误= >控制台错误错误

每次用户在模式窗口中提交表单时,我们都会从表单元素中获取信息并将其发送到后端,这取决于操作URL和方法(帖子).然后,我们将以包含新注释数据的HTML块的形式获得结果。当我们添加一个笔记时,我们只会将它添加到主页列表的顶部,当我们更新一个笔记时,我们会在笔记视图中替换新笔记的内容。

添加对服务器上视图的支持

为了使用视图,我们必须将它们包含在控制器中,并添加所需的设置。

在我们的server.js文件,让我们导入节点路径在文件顶部的实用程序,因为我们在代码中使用它来指示视图的路径:

常量路径=需要“路径”

现在,替换server.route(路线);与下面的代码块对齐:

等待服务器注册需要“@hapi /愿景”服务器的观点引擎哈巴狗需要“哈巴狗”路径路径加入__dirname“lib /视图”compileOptions漂亮的isCached设置env= = =“生产”//添加路由服务器路线路线

在我们添加的代码中,我们首先注册愿景插件和我们的Hapi.js服务器,它将提供视图功能。然后我们为我们的视图添加设置——比如我们将要使用的引擎和视图所在的路径。在代码块的末尾,我们重新添加我们的路由。

这将使我们的视图在服务器上工作,但我们仍然必须声明我们将用于每个路由的视图。

设置主视图

打开lib /控制器/ home.js文件并替换返回声明如下:

返回h视图“回家”数据笔记结果页面“家-便签板”描述“欢迎来到我的笔记板”

在注册Vision插件之后,我们现在有了一个视图方法在应答对象上可用。我们将用它来选择首页查看我们的的观点目录,并发送将在呈现视图时使用的数据。

在提供给视图的数据中,我们还包括页面标题和搜索引擎的元描述。

如果你想在这个时候尝试一些东西,请转到http://localhost:3000/.你会看到一个漂亮的便签板,上面有一个发布不做任何事情的按钮。

设置备注视图:创建函数

现在,每当我们创建一个笔记时,我们都会从服务器向客户端发送一个JSON对象。但是,由于我们使用Ajax处理这个过程,所以可以将新注释作为HTML发送,以便添加到页面中。要做到这一点,我们渲染请注意组件与我们拥有的数据。

开始要求帕格在顶部控制器/ note.js文件:

常量哈巴狗=需要“哈巴狗”

然后,在创建方法,替换行返回结果;使用以下代码块:

//生成一个带有'result'数据的新记录返回哈巴狗renderFile路径加入__dirname“. . /视图/组件/ note.pug”请注意结果

我们使用renderFile方法使用我们刚从模型中接收到的数据来渲染注释模板。

设置备注视图:函数

当我们进入一个笔记页面时,我们应该得到带有笔记内容的笔记模板。要做到这一点,我们必须替换函数的返回注意;这样行:

返回h视图“注意”请注意页面$ {请注意标题-笔记板描述请注意描述

与主页一样,我们选择一个视图作为第一个参数,而将使用的数据作为第二个参数。

设置备注视图:更新函数

每当我们更新一个笔记时,我们将类似于创建新笔记时的回复。取代返回结果;更新使用以下代码执行函数:

//生成带有更新数据的新记录返回哈巴狗renderFile路径加入__dirname“. . /视图/组件/ note.pug”请注意结果

注意:删除功能不需要视图,因为一旦删除了注释,它就会重定向到主页。

静态文件服务

我们在客户端使用的JavaScript和CSS文件是由Hapi.js从静态/公共/目录中。但这不会自动发生;我们必须向服务器表明我们想要将这个文件夹定义为公共文件夹。这是使用惰性包,您可以使用以下命令安装:

npm安装@hapi /惰性

server.register函数。server.js导入惰性插件,并像这样注册到Hapi:

等待服务器注册需要“@hapi /愿景”需要“@hapi /惰性”

现在我们必须定义提供静态文件的路由,以及它们在服务器文件系统上的位置。中导出对象的末尾添加以下条目routes.js

//静态文件方法“获得”路径“/{参数*}”处理程序目录路径路径加入__dirname“. . /静态/公众”配置描述“提供静态资源”

此路线将使用得到方法,我们用一个包含要公开的目录的对象替换了处理程序函数。

中可以找到有关提供静态内容的更多信息Hapi.js文档

结论

至此,我们有了一个使用MVC架构的非常基本的Hapi.js应用程序。尽管在将应用程序投入生产环境之前还需要注意一些事情(例如输入验证、错误处理、错误页面等等),但这应该是学习和构建自己的应用程序的基础。

如果您想进一步了解这个示例,在完成所有小细节(与体系结构无关)以使其成为健壮的应用程序之后,您可以实现一个身份验证系统,以便只有注册用户能够发布和编辑注释。但你的想象力是有限的,所以请尽情享用应用程序库去镇上吧!

深入Node.js,进一步阅读:

Baidu