使用 Netlify 表单和 Edge 构建和部署 Angular 表单

已发表: 2022-03-10
快速总结↬ Netlify Forms 是一种表单处理功能,可以自动接收来自 HTML 表单的提交。 在本文中,我们将介绍如何将它与 Angular 反应式表单一起使用,以及如何在 Netlify 的托管平台 Netlify Edge 上部署完成的应用程序。

创建应用程序的前端、后端和部署工作流程需要大量工作。 在您的应用程序仅从其用户那里收集有限数量的数据提交的情况下,构建一个完整的后端可能看起来不值得花费时间和精力。 开发完整后端的另一种方法是使用 Netlify Forms。 在本教程中,我将解释如何将 Angular 反应式表单与 Netlify Forms 一起使用。 由于 Netlify 表单仅在部署在 Netlify 上时才有效,我还将说明如何在 Netlify Edge 上部署您的应用程序。

工具包

Angular 反应式表单是一种表单,它具有使用 ReactiveFormsModule 提供程序在组件类中显式创建的结构化数据模型。 为表单视图中的每个输入元素创建一个表单模型。 这个表单模型是 FormControl 类的一个实例,它跟踪表单元素的值。 表单模型是不可变的,因为无论何时对模型进行更改,FormControl 实例都会返回一个新的数据模型,而不是更新旧模型。 它的不变性使变更检测更加有效,并允许使用可观察的运算符更改数据。 由于表单输入元素直接连接到它们的表单模型,它们之间的更新是同步的,不依赖于 UI 渲染。

Netlify 是一个平台,允许您构建、部署和托管使用各种技术构建的站点。 使用 Angular 构建的站点可以托管在 Netlify 上。 Netlify 还提供了许多工具来简化、自动化和增强这些站点的构建和部署。 我们将在本教程中使用它的两个产品:Netlify Edge 和 Netlify Forms。

如前所述,Netlify Forms 是一种表单处理功能,可以自动接收来自 HTML 表单的提交。 它不需要任何提交处理配置,例如创建 API、脚本等。此功能仅适用于部署在 Netlify 上的站点中的表单。 它默认启用,进一步减少了设置表单提交所需的配置。 提交处理是在部署期间设置的,其中站点的 HTML 文件由 Netlify 的构建机器人解析。

Netlify Edge 是一个全球应用程序交付网络,在其上发布站点和应用程序。 它提供了 A/B 测试、回滚、登台和分阶段推出等功能。 Netlify Edge 上的所有部署都是原子的,这意味着只有在所有文件都已上传/更新并且对站点的更改准备就绪时,站点才处于活动状态。 部署站点后,在部署到生产环境时,会在netlify.app上为其分配一个子域。 Netlify Edge 还支持预览和分支部署(暂存、开发等)。

Netlify 表单提交处理之所以有效,是因为构建机器人在部署期间会解析站点上的 HTML 表单。 这些机器人不会发现客户端 Javascript 呈现的表单,例如编译的 Angular 站点中的表单。 因此,Netlify 表单的正常设置不适用于 Angular 表单。

但是,有一个解决方法。 为了让它接收提交,一个隐藏的纯 HTML 表单被添加到index.html文件中。 此表单适用于构建机器人。 提交 Angular 表单时,会向这个隐藏表单发出一个 post 请求,然后由 Netlify Forms 捕获。

在本文中,我们将创建一个响应式表单。 我们还将开发一个服务来向隐藏的 HTML 表单发出 post 请求。 最后,我们会将应用程序部署到 Netlify Edge。

例子

为了说明如何构建应用程序,我们将以许多网站上常见的反馈表为例。 我们将使用此表格收集来自网站用户的评论/投诉、问题和建议以及他们的姓名和电子邮件。 我们还将使用它来收集他们对网站的评级。

要求

要学习本教程,您需要一个 Netlify 帐户并安装 Angular CLI。 如果您没有 CLI,则可以使用 npm 安装它。

 npm install -g @angular/cli

如果您还没有注册 Netlify 帐户,您可以在这里创建一个。 Netlify 通过 Github、Gitlab、Bitbucket 或电子邮件提供注册服务。 根据您选择使用的部署方法,它们可能是其他要求。 它们将在每种部署方法下进行说明。

跳跃后更多! 继续往下看↓

设置应用程序

首先,我们将创建应用程序并将其称为feedback 。 创建它时,在提示中询问时向它添加路由。

 ng new feedback

接下来,我们将生成三个组件:反馈表单、成功提交消息页面和 404 页面。 Netlify Forms 允许您在成功提交表单条目后导航到页面。 这就是我们将使用SuccessComponent的目的。

 ng gc feedback ng gc success ng gc page-not-found

生成组件后,我们将路由添加到app-routing.module.ts文件中AppRoutingModule中的每个页面。

 const routes: Routes = [ { path:'', component: FeedbackComponent }, { path: 'success', component: SuccessComponent }, { path: '**', component: PageNotFoundComponent } ];

我们将使用FormBuilder服务来创建我们的反应式表单。 这是因为它比使用基本表单控件更方便且重复性更少。 要访问它,我们需要在app.module.ts文件中注册ReactiveFormsModule

由于我们将向隐藏的 HTML 表单发出 post 请求,因此我们还必须注册HttpClientModule

 import { ReactiveFormsModule } from '@angular/forms'; import { HttpClientModule } from '@angular/common/http'; @NgModule({ imports: [ // other imports ReactiveFormsModule, HttpClientModule ] }) export class AppModule { }

继续将app.component.html的内容更改为只有路由器插座。

 <router-outlet></router-outlet>

不同的页面将共享一些样式。 所以将下面的样式添加到styles.css 中

 html, body { height: 100%; width: 100%; display: flex; align-items: flex-start; justify-content: center; } h1 { margin: 0; text-align: center; } h1, p, label { font-family: Arial, Helvetica, sans-serif; } p { max-width: 25rem; } #container { border: none; padding: .4rem; border-radius: 0; flex-direction: column; display: flex; } hr { width: 80%; } button { color: white; background-color: black; font-size: large; padding: .5rem; border-radius: .5rem; margin-top: 1rem; } @media screen and (min-height: 700px) { html, body { align-items: center; justify-content: center; } } @media screen and (min-width: 480px) { #container { border: .1rem solid lightgray; padding: 2rem; border-radius: .5rem; } html, body { align-items: center; justify-content: center; } }

创建响应式表单

在我们的FeedbackComponent类中,我们将首先导入我们将用于创建表单的FormBuilder服务。 我们还将导入Validators类以进行表单输入验证。

 import { FormBuilder, Validators } from '@angular/forms';

然后,我们将通过将FormBuilder服务添加到FeedbackComponent构造函数来注入它。

 constructor(private fb: FormBuilder) { }

接下来,我们将使用注入的FormBuilder服务的group方法定义表单模型。 我们还将添加一个errorMsg属性来保存我们在提交表单输入时可能遇到的任何错误。 还包括一个closeError方法,该方法将关闭表单上显示的错误警报。

表单模型中的每个控件都将使用来自Validators类的验证器进行验证。 如果任何输入未通过验证,则表单将无效并且提交将被禁用。 您可以选择将多个验证器添加到表单控件,就像email控件一样。

 export class FeedbackComponent { feedbackForm = this.fb.group({ firstName: ['', Validators.required], lastName: ['', Validators.required], email: ['', [Validators.email, Validators.required]], type: ['', Validators.required], description: ['', Validators.required], rating: [0, Validators.min(1)] }); errorMsg = ''; closeError() { this.errorMsg = ''; } // ... }

在组件的模板 ( feedback.component.html ) 中,我们将添加它。

 <div> <div class="error" [class.hidden]="errorMsg.length == 0"> <p>{{errorMsg}}</p> <span (click)="closeError()" class="close">︎</span> </div> <h1>Feedback Form</h1> <hr> <p>We'd like your feedback to improve our website.</p> <form [formGroup]="feedbackForm" name="feedbackForm" (ngSubmit)="onSubmit()"> <div> <p class="radioOption"> <input formControlName="type" type="radio" name="type" value="suggestion"> <label for="suggestion">Suggestion</label><br> </p> <p class="radioOption"> <input formControlName="type" type="radio" name="type" value="comment"> <label for="comment">Comment</label><br> </p> <p class="radioOption"> <input formControlName="type" type="radio" name="type" value="question"> <label for="question">Question</label><br> </p> </div> <div class="inputContainer"> <label>Description:</label> <textarea rows="6" formControlName="description"></textarea> </div> <div class="inputContainer"> <div> <label>How would you rate our site?</label> <label>{{feedbackForm.value?.rating}}</label> </div> <input formControlName="rating" type="range" name="rating" max="5"> </div> <div class="inputContainer"> <label>Name:</label> <div class="nameInput"> <input formControlName="firstName" type="text" name="firstName" placeholder="First"> <input formControlName="lastName" type="text" name="lastName" placeholder="Last"> </div> </div> <div class="inputContainer"> <label>Email:</label> <input formControlName="email" type="email" name="email"> </div> <div class="inputContainer"> <button type="submit" [disabled]="feedbackForm.invalid">Submit Feedback</button> </div> </form> </div>

请注意,表单元素应该具有与我们刚刚创建的模型相对应的[formGroup]="feedbackForm"属性。 此外,每个输入元素都应具有与模型中对应的表单控件相对应的formControlName=""属性。

要设置表单样式,请将其添加到feedback.component.css

 #options { display: flex; flex-direction: column; } #options label { margin: 0 0 0 .2rem; } .radioOption { margin: 0 0 .2rem 0; } .inputContainer { display: flex; flex-direction: column; margin: .5rem 0 .5rem 0; } label { margin: .5rem 0 .5rem 0; } .nameInput { display: flex; flex-direction: column; } button:disabled { cursor: not-allowed; pointer-events: all; background-color: slategrey; } #ratingLabel { display: flex; justify-content: space-between; margin: .5rem 0 .5rem 0; } #ratingValue { font-weight: bolder; font-size: large; border: .1rem solid lightgray; padding: .4rem .6rem .1rem .6rem; margin: 0; vertical-align: middle; border-radius: .3rem; } .error { color: darkred; background-color: lightsalmon; border: .1rem solid crimson; border-radius: .3rem; padding: .5rem; text-align: center; margin: 0 0 1rem 0; display: flex; width: inherit; } .error p { margin: 0; flex-grow: 1; } textarea, input { margin: .1rem; font-family: Arial, Helvetica, sans-serif; padding: 5px; font-size: medium; font-weight: lighter; } .close { cursor: default; } .hidden { display: none; } @media screen and (min-width: 480px) { #options { flex-direction: row; justify-content: space-around; } .nameInput { flex-direction: row; justify-content: space-between; } }

这是表单的样子:

反馈表
反馈表截图(大预览)

添加隐藏的 HTML 表单

如前所述,我们需要添加一个 Netlify Forms 构建机器人可以解析的隐藏 HTML 表单。 然后,提交将从我们的响应式表单发送到隐藏的 HTML 表单。 HTML 表单放在index.html文件中。

此表单应与响应式表单具有相同的名称。 此外,它还应包含其他三个属性: netlifynetlify-honeypothidden 。 机器人会寻找任何具有netlify属性的表单,以便 Netlify 可以处理来自它们的输入。 添加了netlify-honeypot属性以防止在提交时显示验证码并启用额外的垃圾邮件保护。

 <!doctype html> <html lang="en"> <!-- Head --> <body> <form name="feedbackForm" netlify netlify-honeypot="bot-field" hidden> <input type="text" name="firstName"/> <input type="text" name="lastName"/> <input type="text" name="email"/> <input type="text" name="feedbackType"/> <input type="text" name="description"/> <input type="text" name="rating"/> </form> <app-root></app-root> </body> </html>

需要注意的是,由于您无法设置file输入元素的值,因此您无法使用此方法上传文件。

向隐藏表单发出帖子请求

要将响应式表单的提交发送到 HTML 表单,我们将发出一个包含提交到index.html的 post 请求。 该操作将在FeedbackComponentonSubmit方法中执行。

但是,在我们这样做之前,我们需要创建两件事:一个Feedback接口和一个NetlifyFormsService 。 让我们从界面开始。

 touch src/app/feedback/feedback.ts

该文件的内容将是:

 export interface Feedback { firstName: string; lastName: string; email: string; type: string; description: string; rating: number; }

NetlifyFormsService将包含一个用于提交反馈条目的公共方法、一个用于提交通用条目的私有方法以及另一个用于处理任何错误的私有方法。 您可以为其他表单添加其他公共方法。

要生成它,请运行以下命令:

 ng gs netlify-forms/netlify-forms

submitEntry方法返回一个Observable<string>因为一旦我们将数据发布到表单,Netlify 就会发送一个带有成功警报的 HTML 页面。 这是服务:

 import { Injectable } from '@angular/core'; import { HttpClient, HttpErrorResponse, HttpParams } from '@angular/common/http'; import { Feedback } from '../feedback/feedback'; import { Observable, throwError } from 'rxjs'; import { catchError } from 'rxjs/operators'; @Injectable({ providedIn: 'root' }) export class NetlifyFormsService { constructor(private http: HttpClient) { } submitFeedback(fbEntry: Feedback): Observable { const entry = new HttpParams({ fromObject: { 'form-name': 'feedbackForm', ...fbEntry, 'rating': fbEntry.rating.toString(), }}); return this.submitEntry(entry); } private submitEntry(entry: HttpParams): Observable { return this.http.post( '/', entry.toString(), { headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, responseType: 'text' } ).pipe(catchError(this.handleError)); } private handleError(err: HttpErrorResponse) { let errMsg = ''; if (err.error instanceof ErrorEvent) { errMsg = `A client-side error occurred: ${err.error.message}`; } else { errMsg = `A server-side error occurred. Code: ${err.status}. Message: ${err.message}`; } return throwError(errMsg); } } import { Injectable } from '@angular/core'; import { HttpClient, HttpErrorResponse, HttpParams } from '@angular/common/http'; import { Feedback } from '../feedback/feedback'; import { Observable, throwError } from 'rxjs'; import { catchError } from 'rxjs/operators'; @Injectable({ providedIn: 'root' }) export class NetlifyFormsService { constructor(private http: HttpClient) { } submitFeedback(fbEntry: Feedback): Observable { const entry = new HttpParams({ fromObject: { 'form-name': 'feedbackForm', ...fbEntry, 'rating': fbEntry.rating.toString(), }}); return this.submitEntry(entry); } private submitEntry(entry: HttpParams): Observable { return this.http.post( '/', entry.toString(), { headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, responseType: 'text' } ).pipe(catchError(this.handleError)); } private handleError(err: HttpErrorResponse) { let errMsg = ''; if (err.error instanceof ErrorEvent) { errMsg = `A client-side error occurred: ${err.error.message}`; } else { errMsg = `A server-side error occurred. Code: ${err.status}. Message: ${err.message}`; } return throwError(errMsg); } } import { Injectable } from '@angular/core'; import { HttpClient, HttpErrorResponse, HttpParams } from '@angular/common/http'; import { Feedback } from '../feedback/feedback'; import { Observable, throwError } from 'rxjs'; import { catchError } from 'rxjs/operators'; @Injectable({ providedIn: 'root' }) export class NetlifyFormsService { constructor(private http: HttpClient) { } submitFeedback(fbEntry: Feedback): Observable { const entry = new HttpParams({ fromObject: { 'form-name': 'feedbackForm', ...fbEntry, 'rating': fbEntry.rating.toString(), }}); return this.submitEntry(entry); } private submitEntry(entry: HttpParams): Observable { return this.http.post( '/', entry.toString(), { headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, responseType: 'text' } ).pipe(catchError(this.handleError)); } private handleError(err: HttpErrorResponse) { let errMsg = ''; if (err.error instanceof ErrorEvent) { errMsg = `A client-side error occurred: ${err.error.message}`; } else { errMsg = `A server-side error occurred. Code: ${err.status}. Message: ${err.message}`; } return throwError(errMsg); } }

我们将表单提交作为HttpParams发送。 ContentType的标头应包含在值application/x-www-form-urlencoded中。 responseType选项被指定为text ,因为如果成功,发布到隐藏表单将返回一个 HTML 页面,其中包含来自 Netlify 的一般成功消息。 如果您不包含此选项,则会收到错误消息,因为响应将被解析为JSON 。 下面是通用 Netlify 成功消息的屏幕截图。

表单/Netlify 通用成功消息
Netlify 通用成功消息的屏幕截图(大预览)

FeedbackComponent类中,我们将导入NetlifyFormsServiceRouter 。 我们将使用NetlifyFormsService.submitEntry方法提交表单条目。 如果提交成功,我们会重定向到提交成功的页面并重置表单。 我们将使用Router服务进行重定向。 如果不成功, errorMsg属性将被分配错误消息并显示在表单上。

 import { Router } from '@angular/router'; import { NetlifyFormsService } from '../netlify-forms/netlify-forms.service';

之后,在构造函数中注入NetlifyFormsServiceRouter

 constructor( private fb: FormBuilder, private router: Router, private netlifyForms: NetlifyFormsService ) {}

最后,调用FeedbackComponent.onSubmit中的NetlifyFormsService.submitEntry方法。

 onSubmit() { this.netlifyForms.submitFeedbackEntry(this.feedbackForm.value).subscribe( () => { this.feedbackForm.reset(); this.router.navigateByUrl('/success'); }, err => { this.errorMsg = err; } ); }

创建一个成功的提交页面

当用户完成提交时,Netlify 会返回一条通用的成功消息,如上一节的最后一个屏幕截图所示。 但是,您可以链接回您自己的自定义成功消息页面。 为此,您可以将action属性添加到隐藏的 HTML 表单中。 它的值是您的自定义成功页面的相对路径。 此路径必须以/开头并且相对于您的根站点。

但是,在使用隐藏的 HTML 表单时,设置自定义成功页面似乎不起作用。 如果对隐藏的 HTML 表单的发布请求成功,它会以 HTML 页面的形式返回通用的 Netlify 成功消息。 即使指定了action属性,它也不会重定向。 因此,我们将在使用Router服务提交后导航到成功消息页面。

首先,让我们将内容添加到我们之前生成的SuccessComponent 。 在success.component.html中,添加:

 <div> <h1>Thank you!</h1> <hr> <p>Your feedback submission was successful.</p> <p>Thank you for sharing your thoughts with us!</p> <button routerLink="/">Give More Feedback</button> </div>

要设置页面样式,请将其添加到success.component.css

 p { margin: .2rem 0 0 0; text-align: center; }

这是页面的样子:

提交成功页面
提交成功页面截图(大图预览)

FeedbackComponent类中,我们已经添加了Router服务作为导入并将其注入到构造函数中。 在其onSubmit方法中,请求成功并且表单重置后,我们导航到成功提交页面/success 。 我们使用路由器的navigateByUrl方法来做到这一点。

创建 404 页面

404 页面可能不是必需的,但很高兴拥有。 page-not-found.component.html的内容是:

 <div> <h1>Page Not Found!</h1> <hr> <p>Sorry! The page does not exist.</p> <button routerLink="/">Go to Home</button> </div>

要设置它的样式,请将其添加到page-not-found.component.css

 p { text-align: center; }

这就是 404 页面的样子。

404页
404页面截图(大预览)

部署前修复路由

由于我们使用的是Router服务,我们所有的路由都是在客户端完成的。 如果地址栏中粘贴了指向我们应用程序页面的链接(深层链接)或有页面刷新,我们将向我们的服务器发送该请求。 服务器不包含我们的任何路由,因为它们是在前端配置的,在我们的应用程序中。 在这些情况下,我们将收到 404 状态。

为了解决这个问题,我们需要告诉 Netlify 服务器将所有请求重定向到我们的index.html页面。 这样我们的 Angular 路由器就可以处理它们。 如果您有兴趣,可以在此处和此处阅读有关此现象的更多信息。

我们将首先在src文件夹中创建一个_redirects文件。 _redirects文件是一个纯文本文件,它为 Netlify 站点指定重定向和重写规则。 它应该驻留在站点发布站点目录( dist/<app_name> )中。 我们将它放在src文件夹中,并将其指定为angular.json文件中的资产。 当应用程序被编译时,它将被放置在dist/<app_name>中。

 touch src/_redirects

该文件将包含以下规则。 它表示对服务器的所有请求都应该重定向到index.html 。 我们还在末尾添加了一个 HTTP 状态代码选项,以指示这些重定向应返回200状态。 默认情况下,返回301状态。

 /* /index.html 200

我们要做的最后一件事是在我们的angular.json中的er projects > {your_project_name} > architect > options > assets下添加以下选项。 将其包含在assets数组中:

 { "glob": "_redirects", "input": "src", "output": "/" }

在本地预览您的应用

在部署反馈应用程序之前,最好先对其进行预览。 这使您可以确保您的网站按预期工作。 您可能会发现构建过程导致的问题,例如资源路径中断等。 首先,您必须构建您的应用程序。 然后,我们将使用服务器提供编译后的版本。 我们将使用 lite-server,它是一个用于 Web 应用程序的轻量级实时重载服务器。

注意由于该应用程序尚未部署在 Netlify 上,因此当您尝试发出发布请求时会收到 404 错误。 这是因为 Netlify Forms 仅适用于已部署的应用程序。 您将在表单上看到一个错误,如下面的屏幕截图所示,但是,一旦您部署它,它就会起作用。

反馈表错误
反馈表错误截图(大预览)
  1. 首先,安装 lite-server:
     npm install lite-server --save-dev
  2. 接下来,在您应用的工作区目录中,构建您的应用。 要确保每次文件更改时都运行构建,请将--watch标志传递给它。 编译应用程序后,结果将写入dist/<app name>输出目录。 如果您使用的是版本控制系统,请确保不要签入dist文件夹,因为它是生成的并且仅用于预览目的。
     ng build --watch
  3. 要为已编译的站点提供服务,请针对构建输出目录运行lite-server
     lite-server --baseDir="dist/<app name>"

该站点现在在localhost:3000上提供服务。 在您的浏览器上检查它并确保它在开始部署之前按预期工作。

部署

有多种方法可以将 Angular 项目部署到 Netlify Edge。 我们将在这里介绍三个:

  1. 使用netlify-builder
  2. 使用 Git 和 Netlify Web UI,
  3. 使用 Netlify CLI 工具。

1.使用netlify-builder

netlify-builder 有助于通过 Angular CLI 部署 Angular 应用程序。 要使用此方法,您的应用程序需要使用 Angular CLI v8.3.0 或更高版本创建。

  1. 从 Netlify 仪表板的站点选项卡中,创建一个新项目。 由于我们不会使用 Git 创建项目,请将任何空文件夹拖到标有“将站点文件夹拖放到此处”的虚线边框区域。 这将自动创建一个具有随机名称的项目。 如果您愿意,您可以稍后在站点的域设置下更改此名称。
    创建项目的仪表板屏幕截图
    创建项目的仪表板屏幕截图(大预览)

    这是您创建项目后应该看到的内容。
    示例项目的项目页面的屏幕截图
    示例项目的项目页面截图(大预览)
  2. 在使用此方法进行部署之前,您需要从您的帐户中获取 Netlify 项目的API ID和 Netlify个人访问令牌。 您可以从站点设置中获取项目 API ID。 在站点设置 > 常规 > 站点详细信息 > 站点信息下,您将找到项目的 API ID。
    显示站点设置按钮所在位置的屏幕截图
    显示站点设置按钮所在位置的屏幕截图(大预览)
    显示站点 API ID 在其设置中的位置的屏幕截图
    显示站点 API ID 在其设置中的位置的屏幕截图(大预览)

    您可以在用户设置中获取个人访问令牌。 在User Settings > Applications > Personal access tokens中,单击New Access Token按钮。 出现提示时,输入您的令牌的描述,然后单击生成令牌按钮。 复制您的令牌。 出于持久性的考虑,您可以将这些值存储在项目中的.env文件中,但如果您使用的是版本控制系统,则不要签入此文件。
    显示“用户设置”按钮所在位置的屏幕截图
    显示“用户设置”按钮所在位置的屏幕截图(大预览)
    显示在何处创建个人访问令牌的屏幕截图
    显示在何处创建个人访问令牌的屏幕截图(大预览)
    显示在哪里输入令牌描述的屏幕截图
    显示在哪里输入令牌描述的屏幕截图(大预览)
    显示令牌值的屏幕截图
    显示令牌值的屏幕截图(大预览)
  3. 接下来,使用ng addnetlify-builder添加到您的项目中。
     ng add @netlify-builder/deploy
    安装完成后,系统会提示您添加 API ID 和个人访问令牌。
    显示添加 netlify 构建器提示的屏幕截图
    显示添加 netlify 构建器提示的屏幕截图(大预览)

    在此处添加这些是可选的。 您可以忽略此提示,因为它们将被添加到您的angular.json文件中,如果您使用版本控制系统,该文件通常会被签入。 将这种敏感信息存储在代码仓库中是不安全的。 如果您没有签入此文件,则只需输入您的 API ID 和个人访问令牌。 下面的条目将在architect设置下的angular.json文件中进行修改。
     "deploy": { "builder": "@netlify-builder/deploy:deploy", "options": { "outputPath": "dist/<app name>", "netlifyToken": "", "siteId": "" } }
  4. 剩下的就是通过运行来部署您的应用程序:
     NETLIFY_TOKEN=<access token> NETLIFY_API_ID=<api id> ng deploy
    或者,您可以将其放入脚本中,并在需要部署应用程序时运行它。
     # To create the script touch deploy.sh && echo "NETLIFY_TOKEN=<access token> NETLIFY_API_ID=<api id> ng deploy" >> deploy.sh && chmod +x deploy.sh # To deploy ./deploy.sh
    这是运行此命令后应该看到的输出:
    显示部署结果的屏幕截图
    显示部署结果的屏幕截图(大预览)

2. 使用 Git 和 Netlify Web UI

如果您的 Angular 应用程序代码托管在 Github、Bitbucket 或 Gitlab 上,您可以使用 Netlify 的 Web UI 托管项目。

  1. 在 Netlify 仪表板上的站点选项卡中,单击“ 来自 Git 的新站点”按钮。
    显示用于创建新站点的按钮的屏幕截图
    显示创建新站点按钮的屏幕截图(大预览)
  2. 连接到代码存储库服务。 选择托管应用代码的服务。 系统将提示您授权 Netlify 查看您的存储库。 这将因服务而异。
    显示连接到 Git 提供程序的选项的屏幕截图
    显示连接到 Git 提供程序的选项的屏幕截图(大预览)
  3. 选择您的代码存储库。
    显示可用存储库列表的屏幕截图
    显示可用存储库列表的屏幕截图(大预览)
  4. 接下来,您将指定部署和构建设置。 在这种情况下,选择您要部署的分支,将构建命令指定为ng deploy --prod并将发布目录指定为dist/<your app name>
    显示构建和部署设置的屏幕截图
    显示构建和部署设置的屏幕截图(大预览)
  5. 单击“部署站点”按钮,您就完成了。

3. 使用 Netlify CLI 工具

  1. 首先,安装 Netlify CLI 工具,如下所示:
     npm install netlify-cli -g
    如果安装成功,您应该在终端上看到以下结果:
    显示 Netlify CLI 成功安装结果的屏幕截图
    显示 Netlify CLI 成功安装结果的屏幕截图(大预览)
  2. 接下来,运行以下命令登录 Netlify:
     netlify login
    当您运行此命令时,它将导航到一个浏览器窗口,系统将提示您授权 Netlify CLI。 单击Authorize按钮。 一旦获得授权,您就可以继续关闭选项卡。
    显示请求 Netlify CLI 授权的对话框的屏幕截图
    屏幕截图显示请求 Netlify CLI 授权的对话框(大预览)
    显示授权授予对话框的屏幕截图
    显示授权授予对话框的屏幕截图(大预览)
  3. 要创建新的 Netlify 项目,请在终端上运行以下命令:
     netlify init
    系统将提示您将 Angular 应用程序连接到现有的 Netlify 项目或创建一个新项目。 选择创建和配置新站点选项。
    显示用于创建或连接项目的选项的屏幕截图
    显示用于创建或连接项目的选项的屏幕截图(大预览)
    接下来,选择您的团队和您要部署的站点的名称。 创建项目后,CLI 工具将列出项目的站点详细信息。
    显示新站点详细信息的屏幕截图
    显示新站点详细信息的屏幕截图(大预览)
    之后,CLI 工具将提示您将 Netlify 帐户连接到 Git 托管服务提供商以配置 webhook 和部署密钥。 您不能选择退出。 选择一个登录选项,然后授权 Netlify。
    显示提示连接到 Git 提供程序的屏幕截图
    显示提示连接到 Git 提供程序的屏幕截图(大预览)
    接下来,您将被要求输入构建命令。 采用:
     ng build --prod
    之后,系统会要求您提供要部署的目录。 使用您的应用名称输入dist/<app name>
    显示构建设置提示的屏幕截图
    显示构建设置提示的屏幕截图(大预览)
    最后,该命令将完成并显示此输出。
    显示成功项目初始化结果的屏幕截图
    显示成功项目初始化结果的屏幕截图(大预览)
  4. 要部署应用程序,请运行:
     netlify deploy --prod
    使用--prod标志可确保将构建部署到生产环境。 如果您省略此标志, netlify deploy命令会将您的构建部署到用于测试和预览的唯一草稿 URL。 部署完成后,您应该会看到以下输出:
    显示成功部署结果的屏幕截图
    显示成功部署结果的屏幕截图(大预览)

查看表单提交

可以在您站点的“表单”选项卡下的 Netlify 仪表板上查看表单提交。 您可以在app.netlify.com/sites/<your_site_name>/forms找到它。 在此页面上,将列出您所有的活动表格。 您在隐藏表单元素中放置的名称属性是仪表板上的表单名称。

选择表单后,将列出该表单的所有提交。 您可以选择将所有条目下载为 CSV 文件、将它们标记为垃圾邮件或删除它们。

活动表格列表
站点仪表板上列出的活动表单的屏幕截图(大预览)
表格条目
表单仪表板上列出的表单条目的屏幕截图(大预览)

结论

Netlify Forms 允许您从应用程序收集表单提交,而无需创建或配置后端来执行此操作。 这在只需要收集有限数量的数据(如联系信息、客户反馈、活动注册等)的应用程序中尤其有用。

将 Angular 响应式表单与 Netlify 表单配对允许您构建数据模型。 Angular 反应式表单的另一个好处是它们的数据模型和表单元素彼此同步。 它们不依赖于 UI 渲染。

尽管 Netlify Forms 仅在部署在 Netlify Edge 上时才能工作,但托管平台非常强大,提供了有用的功能,如 A/B 测试,并自动构建和部署应用程序。

  • 查看该项目的源代码 →

您可以在此处继续阅读有关在表单中使用 Netlify 的更多信息。