使用AdonisJS构建Web应用

AdonisJS is a Node.js MVC framework. It offers a stable eco-system to write web servers so that you can focus on business needs over finalizing which package to choose or not. In this tutorial, I’ll be showing you how to build a web app with AdonisJS.

AdonisJS是Node.js MVC框架。 它提供了一个稳定的生态系统来编写Web服务器,因此您可以专注于业务需求,而不是最终确定选择哪个软件包。 在本教程中,我将向您展示如何使用AdonisJS构建Web应用程序。

我们将要建设的 ( What We'll Be Building )

In order to see how to build applications with AdonisJS, we’ll build a simple task list (todo) application. We’ll be using AdonisJS 4.0 in this tutorial. Below is a demo of what the final application will look like:

为了了解如何使用AdonisJS构建应用程序,我们将构建一个简单的任务列表(todo)应用程序。 在本教程中,我们将使用AdonisJS 4.0。 以下是最终应用程序外观的演示:

要求 ( Requirements )

This tutorial assumes you have the following installed on your computer:

本教程假定您在计算机上安装了以下软件:

  • Node.js 8.0 or greater

    Node.js 8.0或更高版本
  • Npm 3.0 or greater

    Npm 3.0或更高

安装Adonis CLI ( Installing Adonis CLI )

We need to first install the Adonis CLI which will help us in creating new AdonisJS applications and also comes with some useful commands:

我们需要首先安装Adonis CLI,这将有助于我们创建新的AdonisJS应用程序,并且还附带了一些有用的命令:

npm i -g @adonisjs/cli

建立新专案 ( Create new project )

We'll start by creating a new AdonisJS application. We'll make use of the adonis CLI.

我们将从创建一个新的AdonisJS应用程序开始。 我们将使用adonis CLI。

adonis new adonis-tasks

The command above will create a new AdonisJS application with the name adonis-tasks using the fullstack app boilerplate. To make sure everything is working as expected, let’s run the newly created app. First, we cd into adonis-tasks and run the command below:

上面的命令将使用全fullstack app样板创建一个名为adonis-tasks的新AdonisJS应用fullstack app 。 为确保一切正常,让我们运行新创建的应用程序。 首先,我们cdadonis-tasks ,并运行如下命令:

adonis serve --dev

Then visit http://127.0.0.1:3333 in your browser, and you should get something similar to the image below:

然后在浏览器中访问http://127.0.0.1:3333 ,您应该获得与下图类似的内容:

Good! Let’s now start fleshing out the application.

好! 现在开始充实该应用程序。

数据库和迁移 ( Database and Migration )

We’ll start by structuring the application database. We’ll be using the AdonisJS migration schema to define our application’s database schema. Before we dive into the migration, let’s quickly take time to setup our database. For the purpose of this tutorial, we’ll be using MySQL. So, we need to install Node.js driver for MySQL.

我们将从构建应用程序数据库开始。 我们将使用AdonisJS迁移模式来定义应用程序的数据库模式。 在进行迁移之前,让我们快速花一些时间来设置数据库。 就本教程而言,我们将使用MySQL 。 因此,我们需要为MySQL安装Node.js驱动程序。

npm install mysql --save

Next, we need to make AdonisJS know we are using MySQL. Taking a look at config/database.js, you see config settings for different databases including MySQL. Though we can easily enter our MySQL settings directly in the config file, that will mean we’ll have to change these settings every time we change our application environment (development, staging, production etc.) which is actually a bad practice. Instead, we’ll make use of environment variables and depending on the environment our application is running on, it will pull the settings for that environment. AdonisJS got us covered here. All we have to do is enter our config settings in the .env file.

接下来,我们需要让AdonisJS知道我们正在使用MySQL。 看一下config/database.js ,您会看到包括MySQL在内的不同数据库的配置设置。 尽管我们可以轻松地直接在配置文件中输入MySQL设置,但这意味着我们每次更改应用程序环境(开发,登台,生产等)时都必须更改这些设置,这实际上是一种不良做法。 取而代之的是,我们将使用环境变量,并且根据我们的应用程序所运行的环境,它将拉动该环境的设置。 AdonisJS在这里介绍了我们。 我们要做的就是在.env文件中输入配置设置。

So, open .env and add the snippet below to it:

因此,打开.env并将以下代码段添加到其中:

// .env

DB_CONNECTION=mysql
DB_HOST=localhost
DB_DATABASE=adonis-tasks
DB_USER=root
DB_PASSWORD=

Remember to update the database name, username and password accordingly with your own database settings.

切记使用您自己的数据库设置相应地更新数据库名称,用户名和密码。

For simplicity our application will have only one database table which we’ll call tasks. The tasks table will contain 3 fields id, title, created_at and updated_at. We’ll make use of the adonis make:migration command to create the migration file:

为简单起见,我们的应用程序只有一个数据库表,我们将其称为tasks 。 任务表将包含3个字段idtitlecreated_atupdated_at 。 我们将使用adonis make:migration命令来创建迁移文件:

adonis make:migration tasks

On prompt choose Create table option and press Enter. This will create a new file within the database/migrations directory. The file name will be a timestamp with the name of the schema (in my case 1504289855390_tasks_schema.js). Open this file and update the up() as below:

在提示符下,选择Create table选项,然后按Enter 。 这将在database/migrations directory创建一个新文件。 文件名将是带有模式名称的时间戳(在我的情况下为1504289855390_tasks_schema.js )。 打开此文件并更新up() ,如下所示:

// database/migrations/1504289855390_tasks_schema.js

up () {
  this.create('tasks', (table) => {
    table.increments()
    table.string('title')
    table.timestamps()
  })
}

The increments() will create an id field with Auto Increment and set as Primary key. The timestamps() will create the created_at and updated_at fields respectively. With that done, we can run the migration:

Auto Increment increments()将创建一个具有Auto Incrementid字段,并将其设置为主Primary keytimestamps()将分别创建created_atupdated_at字段。 完成后,我们可以运行迁移:

adonis migration:run

With our database and table set up, let’s now create a model. We’ll call it Task. Though we won’t be making extensive use of the model in this tutorial, we'll use models over writing plain database queries because they bring ease of use and provide an expressive API to drive the data flow and also allows us use Lucid (AdonisJS ORM). To make a model, we use the adonis CLI make:model command:

设置好数据库和表后,现在创建一个模型。 我们将其称为Task 。 尽管在本教程中我们不会广泛使用该模型,但是我们将使用模型来编写普通的数据库查询,因为它们带来了易用性,并提供了表达性API来驱动数据流,还允许我们使用Lucid(AdonisJS ORM)。 要创建模型,我们使用adonis CLI make:model命令:

adonis make:model Task

This will create a Task.js within the app/Models directory.

这将在app/Models目录中创建Task.js

创建申请路线 ( Creating Application Routes )

Open start/routes.js and update with the snippet below:

打开start/routes.js并使用以下代码段进行更新:

// start/routes.js

Route.get('/', 'TaskController.index')
Route.post('tasks', 'TaskController.store')
Route.delete('tasks/:id', 'TaskController.destroy')

We define three routes for our task list application. The first route will serve as our application landing page. It is bound to the index() of the TaskController (which we’ll create shortly). The second route is a POST request which will handle adding new task to the task list. It is bound to the store() of the TaskController. Lastly, we have a route with a DELETE request which will handle deleting a task. It takes the ID of a task to be deleted as a parameter. It is bound to the destroy() of the TaskController.

我们为任务列表应用程序定义了三个路由。 第一条路线将用作我们的应用程序登录页面。 它绑定到TaskControllerindex() (稍后将创建)。 第二个路由是一个POST请求,它将处理将新任务添加到任务列表的过程。 它绑定到TaskControllerstore() 。 最后,我们有一条带有DELETE请求的路由,该路由将处理删除任务。 它以要删除的任务的ID作为参数。 它绑定到TaskControllerdestroy()上。

创建任务控制器 ( Creating The Task Controller )

Having defined our application’s routes and bind to methods on the TaskController, it's time to create the TaskController itself. Again, we’ll use the adonis CLI command:

定义了应用程序的路由并绑定到TaskController上的方法之后,就该创建TaskController本身了。 同样,我们将使用adonis CLI命令:

adonis make:controller Task

On prompt choose For HTTP requests option and press Enter. Now we have a TaskController.js file within the app/Controllers/Http directory.

在提示符下,选择“ For HTTP requests选项,然后按Enter 。 现在,我们在app/Controllers/Http目录中有一个TaskController.js文件。

** Note:** Before we ran the make:controller command, the app/Controllers/Http wasn’t present. It was created after running the command.

**注意:**在运行make:controller命令之前,尚不存在app/Controllers/Http 。 它是在运行命令后创建的。

As we have seen from the routes above, the TaskController will have 3 methods (index(), store(), and destroy()). Open TaskController.js and add the following code into it:

从上面的路由我们已经看到, TaskController将具有3个方法( index()store()destroy() )。 打开TaskController.js并将以下代码添加到其中:

// app/Controllers/Http/TaskController.js

// remember to reference the Task model at the top
const Task = use('App/Models/Task')

async index ({ view }) {
  const tasks = await Task.all()

  return view.render('tasks.index', { tasks: tasks.toJSON() })
}

The index() simply fetches all the tasks that have been created from the database and renders a view. AdonisJS uses ES7 async/await and ES6 Object Destructuring. The tasks fetched is then passed to a view file tasks.index (which we’ll create shortly).

index()只是从数据库中获取所有已创建的任务并呈现视图。 AdonisJS使用ES7 async / await和ES6对象解构。 然后将获取的任务传递到视图文件tasks.index (稍后将创建)。

创建主版面 ( Creating Master Layout )

AdonisJS makes use of Edge as its templating engine which has support for layouts. We are going to create a master layout for our application. All view files must be within the resources/views directory. So within the directory, let’s create a new view file and name it master.edge. Edge files have the .edge extension. Open the newly created file and paste the following code in it:

AdonisJS将Edge用作支持布局的模板引擎。 我们将为我们的应用程序创建一个主布局。 所有视图文件都必须位于resources/views目录中。 因此,在目录中,我们创建一个新的视图文件并将其命名为master.edge 。 边缘文件具有.edge扩展名。 打开新创建的文件,并将以下代码粘贴到其中:

<!-- resources/views/master.edge -->

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Task List</title>
    {{ css('https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css') }}
    {{ css('https://cdnjs.cloudflare.com/ajax/libs/bulma/0.5.1/css/bulma.min.css') }}
</head>
<body>
    <section class="section">
        <div class="container">
            <div class="columns">
                <div class="column is-8 is-offset-2">
                    @!section('content')
                </div>
            </div>
        </div>
  </section>
</body>
</html>

We are using Bulma CSS framework. We use AdonisJS view’s css() global to reference our css files on CDN. The layout is simple, it contain only one section which is content.

我们正在使用Bulma CSS框架。 我们使用全局的AdonisJS视图的css()来引用CDN上的css文件。 布局很简单,只包含一个content部分。

Tips: The ! within @!section() indicate that it is a self closing section.

提示: ! @!section()表示这是一个自闭节。

创建任务视图 ( Creating The Task View )

For simplicity our task list application will have just one view file. Every view specific stuff will be done within this view file. We are going to place this view within a tasks directory. Create a new directory named tasks within the resources/views directory, then within the task directory, create a new view file and name it index.edge. Now, open the index.edge file and paste the following code into it:

为简单起见,我们的任务列表应用程序将只有一个视图文件。 每个视图特定的内容都将在此视图文件中完成。 我们将把这个视图放在一个tasks目录中。 在resources/views目录中创建一个名为tasks的新目录,然后在task目录中创建一个新的视图文件并将其命名为index.edge 。 现在,打开index.edge文件并将以下代码粘贴到其中:

<!-- resources/views/tasks/index.edge -->

@layout('master')

@section('content')
  <div class="box">
    <h1 class="title">Task List</h1>

      <table class="table is-bordered is-striped is-narrow is-fullwidth">
        <thead>
          <tr>
            <th>SN</th>
            <th>Title</th>
            <th>Action</th> 
          </tr>
        </thead>
        <tbody>
          @each(task in tasks)
            <tr>
              <td>
                {{ ($loop.index + 1) }}
              </td>
              <td>
                {{ task.title }}
              </td>
              <td>
                <button class="button is-danger is-outlined">
                  <span>DELETE</span>
                  <span class="icon is-small">
                    <i class="fa fa-times" aria-hidden="true"></i>
                  </span>
                </button>
              </td>
            </tr>
          @else
            <tr>
              <td colspan="3" class="has-text-centered">No task created yet!</td>
            </tr>
          @endeach
        </tbody>
      </table>
  </div>
@endsection

First, we indicate we are using the master layout we created above. We simply display the tasks in a table. If there are no tasks, we display a appropriate message. For the SN of the tasks, we are using the index property of Edge’s $loop variable. The index property holds the iteration index, which starts from 0, hence the addition of 1. Lastly, we have a delete button which does nothing for now.

首先,我们指示我们正在使用上面创建的master布局。 我们仅在表中显示任务。 如果没有任务,我们将显示一条适当的消息。 对于任务的SN ,我们使用Edge的$loop变量的index属性。 index属性保存从0开始的迭代索引,因此加了1。最后,我们有一个delete按钮,该按钮目前不执行任何操作。

If we visit the application in the browser, since we haven’t added any tasks yet, we should get something similar to the image below:

如果我们在浏览器中访问该应用程序,则由于尚未添加任何任务,因此我们应获得类似于下图的内容:

添加新任务 ( Adding New Task )

Let’s update the index.edge file to include a form for adding a new task. Add the following code immediately after @section('content'):

让我们更新index.edge文件,使其包含用于添加新任务的表单。 在@section('content')之后立即添加以下代码:

<!-- resources/views/tasks/index.edge -->

<div class="box">
  <h2 class="title">New Task</h2>

  <form action="/tasks" method="POST">
    {{ csrfField() }}

    <div class="field has-addons">
      <div class="control is-expanded">
        <input class="input" type="text" name="title" value="{{ old('title', '') }}" placeholder="Task title">
      </div>
      <div class="control">
        <button type="submit" class="button is-primary">
            Add Task
        </button>
      </div>
    </div>

    {{ elIf('<p class="help is-danger">$self</p>', getErrorFor('title'), hasErrorFor('title')) }}
  </form>
</div>

It’s a simple form with one field for the title of the task. We also add a CSRF field since AdonisJS by default prevent us from CSRF attacks. Lastly, we display a validation error message if the form fails validation.

这是一种简单的表单,其中一个字段表示任务的标题。 我们还添加了CSRF字段,因为默认情况下,AdonisJS会阻止我们遭受CSRF攻击。 最后,如果表单验证失败,我们将显示验证错误消息。

Next, we need to create the store() that will handle adding a new task to the database. Before we create this method, let’s quickly setup Adonis validator which will be used for validating our form. The validator is not installed by default, so we need to install it first:

接下来,我们需要创建store()来处理将新任务添加到数据库的操作。 在创建此方法之前,让我们快速设置Adonis验证器,该验证器将用于验证我们的表单。 默认情况下未安装验证器,因此我们需要先安装它:

adonis install @adonisjs/validator

Next, we need to register the provider inside start/app.js:

接下来,我们需要在start/app.js注册提供者:

const providers = [
  ...
  '@adonisjs/validator/providers/ValidatorProvider'
]

Now, let’s create the store() in TaskController.js. Paste the snippet below just after the index():

现在,让我们在TaskController.js创建store() 。 将代码段粘贴在index()

// app/Controllers/Http/TaskController.js

//  remember to reference the Validator at the top
const { validate } = use('Validator')

async store ({ request, response, session }) {
  // validate form input
  const validation = await validate(request.all(), {
    title: 'required|min:3|max:255'
  })

  // show error messages upon validation fail
  if (validation.fails()) {
    session.withErrors(validation.messages())
            .flashAll()

    return response.redirect('back')
  }

  // persist to database
  const task = new Task()
  task.title = request.input('title')
  await task.save()

  // Fash success message to session
  session.flash({ notification: 'Task added!' })

  return response.redirect('back')
}

First, we validate the requests coming from the form against some rules. If the validation fails, we simply save the validation messages to the session and return back to the form with the error messages. If everything went well, we persist the new task to the database and flash a notification message indicating that the task was added successfully then redirect to the form.

首先,我们根据一些规则验证来自表单的请求。 如果验证失败,我们只需将验证消息保存到会话中,然后返回包含错误消息的表单。 如果一切顺利,我们会将新任务保留到数据库中,并闪烁一条通知消息,指示已成功添加任务,然后重定向到表单。

显示通知 ( Displaying Notification )

Next, we need to a way to display the notifications. Open resources/views/tasks/index.edge, between the first (add task) and second (task list) .box elements, add the snippet below:

接下来,我们需要一种显示通知的方法。 在第一个(添加任务)和第二个(任务列表) .box元素之间打开resources/views/tasks/index.edge ,在下面添加代码段:

<!-- resources/views/tasks/index.edge -->

@if(old('notification'))
    <div class="notification is-success">
        {{ old('notification') }}
    </div>
@endif

With that done, we can now add tasks to the task list. You should get something similar to the image below:

完成之后,我们现在可以将任务添加到任务列表中。 您应该获得类似于下图的内容:

删除任务 ( Deleting a Task )

The last functionality our task list application will have is “deleting tasks”. To achieve this, we need to update the dummy delete button created earlier to include actual form for deleting a specific task. Replace the delete button entirely with the code below:

我们的任务列表应用程序的最后一项功能是“删除任务”。 为此,我们需要更新之前创建的虚拟删除按钮,以包括用于删除特定任务的实际形式。 将删除按钮完全替换为以下代码:

<!-- resources/views/tasks/index.edge -->

<form action="{{ 'tasks/' + task.id + '?_method=DELETE' }}" method="POST">
  {{ csrfField() }}

  <button type="submit" class="button is-danger is-outlined">
    <span>DELETE</span>
    <span class="icon is-small">
      <i class="fa fa-times" aria-hidden="true"></i>
    </span>
  </button>
</form>

Remember the route handling deleting of task accepts the ID of the task as a parameter, so we are attaching the task ID to the form action. Also, we are passing the request method (DELETE in this case) as query string. This is the AdonisJS way of doing method spoofing, since HTML forms aren’t capable of making requests other than GET and POST.

请记住,删除任务的路由处理会接受任务的ID作为参数,因此我们将任务ID附加到表单操作中。 另外,我们将请求方法(在本例中为DELETE )作为查询字符串传递。 这是AdonisJS进行方法欺骗的方式,因为HTML表单除了GETPOST之外都无法发出请求。

Next, we add the destroy() to TaskController.js. Paste the code below into it just after the store():

接下来,我们将destroy()添加到TaskController.js 。 将以下代码粘贴到store()

// app/Controllers/Http/TaskController.js

async destroy ({ params, session, response }) {
  const task = await Task.find(params.id)
  await task.delete()

  // Fash success message to session
  session.flash({ notification: 'Task deleted!' })

  return response.redirect('back')
}

We first get the ID of the task from the params object and then use it to retrieve the task from the database. We then delete the task thereafter. Lastly, we flash an appropriate message and redirect back to the page.

我们首先从params对象获取任务的ID,然后使用它从数据库中检索任务。 然后,我们随后删除任务。 最后,我们刷新一条适当的消息,然后重定向回页面。

Below is what we get when we delete the task added above:

以下是删除上面添加的任务后得到的结果:

结论 ( Conclusion )

That’s it. We have been able to build a simple application with AdonisJS. Though this tutorial only covered the basics of AdonisJS, it should get you started in building your application with AdonisJS. I hope you find this tutorial helpful. If you have any questions, suggestions, comments, kindly leave them below.

而已。 我们已经能够使用AdonisJS构建一个简单的应用程序。 尽管本教程仅介绍了AdonisJS的基础知识,但它应该可以帮助您开始使用AdonisJS构建应用程序。 希望本教程对您有所帮助。 如果您有任何问题,建议或意见,请将它们留在下面。

翻译自: https://scotch.io/tutorials/building-a-web-app-with-adonisjs

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值