使用Sails.js v1.0 + Angular5进行单页应用开发的入门指南

首先

这篇文章 is about

这是一篇介绍如何在Sails.js作为服务器端,Angular5作为前端,搭建一个简单单页应用(SPA)的循环的文章。主要涉及环境设置方面的内容。

目标对象

从未使用过Node.js的人也是适用的。

Sails.js 是什么

这个框架,正如其名称所示,可以使用Node.js来创建类似于Rails的MVC web应用程序。它主要负责服务器端的工作。实际上,它似乎是建立在express框架的基础之上。

Angular是一种前端开发框架。

一种由谷歌开发的前端JS框架,支持TypeScript,使用起来更加便捷。

环境

操作系统:Windows10
Node.js 版本:v9.8.0
Yarn 版本:1.5.1
@angular/cli 版本:1.7.4
@angular/core 版本:5.2.10
Sails 版本:1.0.0

参考文章

开始之前

如果您已经进行了安装,请忽略以下步骤。

线

Yarn是一种与npm兼容的包管理软件。通过yarn.lock文件,可以精确地指定安装的版本,从而确保在一个环境中可以完成的工作在其他环境中也一定可以完成。

因为有很多方便之处,所以我们把它装进去吧。

如果安装了chocolatey(https://chocolatey.org/),可以使用以下命令进行安装。

choco install yarn

角度/命令行界面 (Angular/CLI)

@angular/cli是一个用于简化Angular开发的客户端工具。
特别是在构建、生成组件和启动模拟服务器等方面,它能够以最佳实践的方式处理原本需要手动进行各种设置的工作,非常优秀。

由于本文章基本上依赖于此观点,我们应该将其加入。

yarn global add @angular/cli

Sails.js 帆船.js

请放进去吧。

yarn global add sails

邮递员 dì

这是一个非常方便的 Chrome 扩展程序,用于调用 API。
可以从 Chrome 网上应用店获得,建议获取并安装。
也可以使用 curl。

开始学习Angular

创造一个新的项目(ng new)。

在Angular开发中,基本上使用之前安装的@angular/cli工具。
@angular/cli的命令是“ng”。

我们马上开始吧。

cd ルートにしたいフォルダ
ng new qiita_angular

「qiita_angular」可以隨便選,沒關係。

在这里创建的文件夹将来会变得无用,所以不需要太认真地考虑。

然后,会创建如下的文件夹。

└─qiita_angular
    ├─e2e
    ├─node_modules
    └─src
        ├─app
        ├─assets
        └─environments

其中,作为源代码触摸的部分主要位于 src/app 目录下。

先试着启动dev-server。

Angular组件分为模板文件和处理模板的ts文件。为了确认Angular组件可以显示出来,我们先来看看src/app/app.component.html这个文件。

<!--The content below is only a placeholder and can be replaced.-->
<div style="text-align:center">
  <h1>
    Welcome to {{ title }}!
  </h1>
...

我认为会变成这样。
在这里所说的“title”中,是指src/app/app.component.ts中的“title”,
那么我们试着把这里的值从“app”改为“qiita”。

export class AppComponent {
  title = 'app';
}

过去的是

export class AppComponent {
  title = 'qiita';
}

我們來確認一下,在更換的狀態下,組件是否正確顯示出來。

如果要在Angular应用程序中显示@angular/cli,可以使用以下命令。

ng serve

如果出现以下消息,则表示成功。

** NG Live Development Server is listening on localhost:4200, open your browser on http://localhost:4200/ **
Date: 日付
Hash: ハッシュ値
Time: 時間
chunk {inline} inline.bundle.js (inline) 3.85 kB [entry] [rendered]
chunk {main} main.bundle.js (main) 18 kB [initial] [rendered]
chunk {polyfills} polyfills.bundle.js (polyfills) 554 kB [initial] [rendered]
chunk {styles} styles.bundle.js (styles) 41.5 kB [initial] [rendered]
chunk {vendor} vendor.bundle.js (vendor) 7.43 MB [initial] [rendered]

webpack: Compiled successfully.

让我们打开 http://localhost:4200 看一看。
如果出现「欢迎来到 Qiita!」的字样,那就表示成功了。

制作组件

因此,让我们尝试创建一个像创建博客文章一样的组件类型。在Angular中,我们将常规的HTML定义为”页面”,也将其定义为”组件”。

首先我們來試試從@angular/cli生成組件。

在Qiita_angular/目錄下

ng generate component qiita

我想你会发现在src/app下创建了一个名为”qiita”的目录。

当你查看qiita.component.html可以看到以下内容。

<p>
  qiita works!
</p>

暂时先试试这个方法。根据查看qiita.component.ts文件,这个组件似乎可以通过”app-qiita”这个标签来嵌入,所以我会把app.component.html修改如下试试看。

<!--app.component.html-->
<div style="text-align:center">
  <h1>
    Welcome to {{ title }}!
  </h1>
</div>

<app-qiita></app-qiita>

当你在这种状态下访问localhost:4200时,

Welcome to qiita!
qiita works!

我认为会这样出来。

定义组件的内容

由于这个机会难得,我们尝试使用文本输入框、文本输入框和按钮来制作一个像博客一样的页面吧。

由于ngModel在双向绑定中非常方便,所以我们会使用它。为了使用ngModel,我们需要在app.module.ts中导入FormsModule,所以让我们不加思考地导入它。

// app.modules.ts
...
import { FormsModule } from '@angular/forms';
...

@NgModule({
  declarations: [
    AppComponent,
    QiitaComponent,
  ],
  imports: [
    BrowserModule,
    FormsModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

<!-- qiita.component.html -->
<p>
  <input type="text" [(ngModel)]="title">
</p>
<p>
  <textarea [(ngModel)]="body">
</p>
<p>
  <button (click)="onClickRegister()">登録</button>
</p>
// qiita.component.ts
export class QiitaComponent implements OnInit {

  title:string;
  body:string;

// ...

  onClickRegister() {
    console.log(this.title);
    console.log(this.body);
  }

}

这样做的话,我想它至少会变得像博客风格。
每个人应该设法解决外观难看的问题。

创建服务 fuwù)

“在Angular中,将业务逻辑风格的内容剥离到服务层。
在本例中,将注册和加载逻辑放置在服务层中。”

服务定义

首先,我们从@angular/cli创建一个服务。

ng generate service qiita/qiita

所以,在/src/app/qiita下生成了qiita.service.ts。

先先制性地先制注册和加载的API吧,毕竟既然是异步的,就用async吧。

@Injectable()
export class QiitaService {

  constructor() { }

  public async load(id:number):Promise<any> {
    return new Promise((resolve)=>{
      resolve({title:'hoge',body:'fuga'});
    });
  }

  public async register(blog:any):Promise<any> {
    return new Promise((resolve)=>{
      resolve({title:blog.title,body:blog.title,id:1});
    });
  }

}

内容仍需进一步完善。

向组件注入

创建的服务将以DI方式组件可使用。带有@Injectable修饰的服务类将自动实例化并被传入组件的构造函数参数中。然而,请确保在@Component的providers参数中指定服务类。

太好了。

// qiita.component.ts
import { Component, OnInit } from '@angular/core';
import { QiitaService } from './qiita.service'; // 足す

@Component({
  selector: 'app-qiita',
  templateUrl: './qiita.component.html',
  providers : [ QiitaService ], // 足す
  styleUrls: ['./qiita.component.css']
})
export class QiitaComponent implements OnInit {

  title:string;
  body:string;

  constructor(private service:QiitaService) { } // 足す

如果按照这样的方式进行,您可以随时从`this.service`调用先前定义的服务类的实例。

由于在前面的onClickRegister()上增加的可能性正好,因此我们正好可以添加它。

  onClickRegister() {
    this.service.register({title:this.title,body:this.body}).then(res=>{
     console.log(res);
    });
  }

您讲的很像了。

安裝路由器 lù qì)

我們希望這次創建一個SPA,所以要先準備路由器。
SPA是指Single Page Application的縮寫,它是一種架構,不需進行頁面跳轉時的同步通信,
而是使用JS來在視覺上切換頁面。

在这里所说的”页面转换”是指

    • アドレスバーにアドレスを打ち込む

 

    ブラウザの戻る、進むボタン

我所说的是Angular控制浏览器的返回、前进按钮和地址栏。真是太厉害了。

如果开始使用路由器,需要以下步骤:

    • Routesを設定する。

 

    • app.module.tsにRouterModuleとRoutesをインポートする。

を配置する

设置路由。

我会将路由设为外部部分。
在app.module.ts的同一级目录中创建一个”routes.ts”文件,并按照以下方式进行设置。

// routes.ts
import { Routes } from '@angular/router';
import { QiitaComponent } from './qiita/qiita.component';

export const routes : Routes = [
    {path : 'blog' , component : QiitaComponent }
];

我要在app.module.ts中导入RouterModule和Routes。

是一样的。

将在app.modules.ts中定义的routes导入。
最终将变成这样的样子。

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router'; // 足す。
import { AppComponent } from './app.component';
import { QiitaComponent } from './qiita/qiita.component';
import { FormsModule } from '@angular/forms';
import { routes } from './routes'; // 足した

@NgModule({
  declarations: [
    AppComponent,
    QiitaComponent,
  ],
  imports: [ 
     // ここから
    RouterModule.forRoot(
      routes,{useHash : true}
    ),
    //  ここまで足した
    BrowserModule,
    FormsModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

放置一个router-outlet

如果要设置路由器,需要告诉我将组件显示在哪里。

由于本次我们使用了bootstrap:[AppComponent],因此会在AppComponent内显示与Router匹配的组件的图像。

所以将app.component.html按照以下方式进行修改。

<!--app.component.html-->
<div style="text-align:center">
  <h1>
    Welcome to {{ title }}!
  </h1>
</div>

<router-outlet></router-outlet>

补充:关于 useHash

使用 useHash 选项后,URL 格式将为 http://localhost:4200/#/blog。通过这样的设置,当直接通过 URL 访问时,服务器会将“/”及其以下部分视为可见行为,而浏览器渲染部分将始终通过 Angular 的路由而非服务器端路由进行处理。为了与 Sails.js 路由器共存,我们决定使用 useHash。

迄今为止的操作确认

http://localhost:4200/#/blog を叩いて、テキストエリアとインプット、ボタンが表示されること。
welcome to qiita!と表示されること。

我希望能保证这一带。

在这个地区,我们应该先写完E2E。

@angular/cli的e2e默认使用了一个叫做protractor的工具。虽然我没有使用过,但我们可以先参考一下app.e2e-spec.ts文件来试试看。

用中文重新表达以下内容,只需要一个版本:

应用端到端

由于我们正在测试的是app.e2e,并且标题的字符是“app”,所以这次我们将其更改为“qiita”,同时也要改变期望值。

//app.e2e-spec.ts
  it('should display welcome message', () => {
    page.navigateTo();
    expect(page.getParagraphText()).toEqual('Welcome to qiita!'); // ここを変えた
  });

qiita.e2e和qiita.po

请模仿app.e2e-spec.ts和app.po.ts,创建qiita.e2e-spec.ts和qiita.po.ts。

「po」是Page Object的缩写,我会在这里写上选择器等内容。

// qiita.po.ts

import { browser, by, element } from 'protractor';

export class QiitaPage {
  navigateTo() {
    return browser.get('/#/blog');
  }

  getInput() {
    return element(by.css('input'));
  }

  getTextArea() {
    return element(by.css('textarea'));
  }

  getButtonText() {
    return element(by.css('button')).getText();
  }
}

挺不错的啊。

// qiita.e2e-spec.ts
import { QiitaPage } from './qiita.po';

describe('qiita App', () => {
  let page: QiitaPage;

  beforeEach(() => {
    page = new QiitaPage();
  });

  it('should display textarea and input and button', () => {
    page.navigateTo();
    expect(page.getInput()).toBeTruthy();
    expect(page.getTextArea()).toBeTruthy();
    expect(page.getButtonText()).toEqual('登録');
  });
});

至少可以确保有一个名为“输入”、一个名为“文本输入”、和一个名为“注册”的按钮元素。这被称作烟雾测试,在初始环境配置阶段应该足够了。

亚里马丝塔内

进一步的路由器

既然那么辛苦去注册了博客,让我们把它设为可见吧。

在routes.ts文件中添加路由。

{path : 'blog/:id' , component : QiitaComponent }

听起来像是加载并展示与id参数匹配的博客文章。很好呢。

既然如此,我们来在ngOnInit函数中添加载入处理吧。

// qiita.component.ts
import { ActivatedRoute } from '@angular/router'; // 追加

...

  constructor(private service:QiitaService,private route : ActivatedRoute) { } // ActivatedRouteを追加。

  ngOnInit() { // 書き換え。
    this.route.params.subscribe(params=>{
      let id = params['id'];
      if(!id) {
        return;
      }
      this.service.load(id).then(blog=>{
        this.title = blog.title;
        this.body = blog.body;
      });
    });
  }

从路由器获取参数然后进行加载的感觉已经非常不错了。

既然这样的话,我们最好在注册后进一步转到查询页面。

// qiita.component.ts
  constructor(private service:QiitaService,private route : ActivatedRoute,private router : Router) { } // routerを追加
...
  onClickRegister() {
      this.service.register({title:this.title,body:this.body}).then(res=>{
       this.router.navigate(['blog/' + res.id]); // 遷移するように。
      });
  }

好的,由于对组件进行了各种调整,所以让我们在这里运行端对端测试吧。

ng e2e

可以执行端到端测试。

因为我们希望在加载时也能够测试显示的内容,所以让我们尝试将PageObject设置成这个样子。

// qiita.po.ts
export class QiitaPage {
  navigateTo(id?:number) {
    return browser.get('/#/blog' + (id ? '/' + String(id) : ''));
  }

然后做测试代码。

// qiita.e2e-spec.ts
...
  it('should display textarea and input and button even when an id specified.', () => {
    page.navigateTo(1);
    expect(page.getInput()).toBeTruthy();
    expect(page.getTextArea()).toBeTruthy();
    expect(page.getButtonText()).toEqual('登録');
  });
});

我会再试一次。

ng e2e

好棒哦~

暫時先確認完Angular的內容。

开始航行

创建新项目

暫時先建立一個專為Sails而設的資料夾,我會命名為qiita_sails。在qiita_sails底下進行。

sails new

让我们试试看。

 1. Web App  ·  Extensible project with auth, login, & password recovery
 2. Empty    ·  An empty Sails app, yours to configure
 (type "?" for help, or <CTRL+C> to cancel)
?

鉴于麻烦,我会选择方案2。

Sails的目录结构

qiita_sails
├─api
│  ├─controllers
│  ├─helpers
│  ├─models
│  └─policies
├─assets
│  ├─dependencies
│  ├─images
│  ├─js
│  ├─styles
│  └─templates
├─config
│  ├─env
│  └─locales
├─tasks
│  ├─config
│  └─register
└─views
    ├─layouts
    └─pages

以下是這種感覺。
基本上,“api”以下是需要修改的地方。
不過,“config”以下也值得一看,可以學到相當多的知識,所以讓我們大致看一遍吧。

sails.config可以被重新表述为”帆.config”。

我将介绍一些亮点。

数据存储.js (原连接.js)

通过使用被称为适配器的插件集,可以连接到各种不同的数据库。

根据https://sailsjs.com/plugins/databases,官方支持的数据库是MySQL、PostgreSQL和MongoDB。
默认情况下,sails-disk是内置的数据库配置,可以使用。 sails-disk数据库的内容以JSON格式保存在.tmp/localDiskDb中,因此可以查看。

暫時我們不會設置任何特定事項,但在這裡是可以進行設定的。

安全.js(以前的cors.js,csrf.js)

可以进行安全设置。

由于Angular已经准备好调用API,所以我们可以在以后再开启CSRF防护。

由于我想要通过Postman(或者curl)进行操作确认,所以暂时将其保持关闭状态。

模型.js

Sails与Rails一样,通过OR映射器进行数据库操作。
它能够自动执行环境迁移,以保证与定义的数据模型和数据库表(或集合)相匹配。

需要设置如何处理它,但是暂时先设定为「alter」。(当模型发生变化时,通过alter表来实现相应的策略)

除了删除表格(drop)和不进行任何操作(safe)之外,还有其他选项可供选择。

  /***************************************************************************
  *                                                                          *
  * How and whether Sails will attempt to automatically rebuild the          *
  * tables/collections/etc. in your schema.                                  *
  *                                                                          *
  * > Note that, when running in a production environment, this will be      *
  * > automatically set to `migrate: 'safe'`, no matter what you configure   *
  * > here.  This is a failsafe to prevent Sails from accidentally running   *
  * > auto-migrations on your production database.                           *
  * >                                                                        *
  * > For more info, see:                                                    *
  * > https://sailsjs.com/docs/concepts/orm/model-settings#?migrate          *
  *                                                                          *
  ***************************************************************************/

  migrate: 'alter',

创建API

这次我们将创建一个名为Blog的模型,并使其能够进行CR(UD)操作。
(关于Update和Delete,本文将省略掉。)

Sails和Rails一样,可以通过命令行自动创建模型和控制器。

sails generate api blog

假设在api/controllers目录下生成了BlogController.js文件,在api/models目录下生成了Blog.js文件。

Sails.js通过其蓝图功能,在创建模型和控制器时自动创建CRUD的REST API。

说到这里,关于Sails方面要做的事情就在此结束了。

启动服务器

sails lift

是的。

让我们先访问 http://localhost:1337 并确认是否会出现一些内容。

试着调用API。

这次我们将使用Chrome扩展程序“Postman”。
您也可以使用curl,根据需要自行调整。

邮递

暫時先嘗試創建。

使用以下参数:
– title: “新しいブログのタイトル”
– content: “新しいブログのコンテンツ”

title : hoge
body : fuga

我将输入类似这样的内容并从”发送”按钮发送。

获取

成功时,您应该会收到创建的资源内容的返回。请记下其”ID”,然后尝试发送以下的GET请求。

将方法设为“GET”,在不发送请求主体的情况下,使用以下链接:
http://localhost:1337/blog/前面的ID

我认为会返回之前创建的资源。

如果是这样,列表将以数组的形式返回。

太好了。

放置

我放弃了。

删除

我决定放弃。

将Sails.js与Angular5集成在一起。

本题的任务是,

    • Angular側はビルドだけしておき、成果物を吐く。

 

    • Sails側は成果物をアセットパイプラインで受け取り、サーバー上に配置する。

 

    Angular側がビルドした結果できるindex.htmlを、Sails側のテンプレートエンジンでインクルードして表示する。

会有这种感觉。
我会按顺序进行。

将Angular项目放置在assets文件夹下

在qiita_sails下的assets文件夹下创建一个目录。
我决定把它命名为angular。

然后,从您刚刚创建的Angular项目的目录中,将src目录移植过来。

哦拉

qiita_sails
├─api
│  ├─controllers
│  ├─helpers
│  ├─models
│  └─policies
├─assets
│  ├─angular
│  │  ├─app
│  │  │  └─qiita
│  │  ├─assets
│  │  └─environments
│  ├─dependencies
│  ├─images
│  ├─js
│  ├─styles
│  └─templates
├─config
│  ├─env
│  └─locales
├─tasks
│  ├─config
│  └─register
└─views
    ├─layouts
    └─pages

应该会变成这种感觉

将与@angular/cli相关的设置移植过来。

接下来,把.angular-cli.json文件复制到package.json所在的目录中。
然后将tsconfig.json文件复制到assets/目录下。

接下来,.angular-cli.json文件中包含有相对路径,我将对其进行修正。

首先是“应用程序”以下的“根目录”。

我会把它改写成这样。

"apps": [
    {
      "root": "assets/angular",
      "outDir": "assets/dist",

让我们也同样处理 “lint”。
但是“e2e”稍后会放到另一个地方,所以暂时按照以下方式处理好。

  "lint": [
    {
      "project": "assets/angular/tsconfig.app.json",
      "exclude": "**/node_modules/**"
    },
    {
      "project": "assets/angular/tsconfig.spec.json",
      "exclude": "**/node_modules/**"
    },
    {
      "project": "e2e/tsconfig.e2e.json",
      "exclude": "**/node_modules/**"
    }
  ],

移植 package.json 的依赖关系。

我从原始Angular项目的package.json中将依赖项移植到sails项目的package.json中。在这里我只需要随意进行。

这只是作者的构思,供您参考。

  "dependencies": {
    "sails": "^1.0.0",
    "grunt": "1.0.1",
    "sails-hook-grunt": "^3.0.2",
    "sails-hook-orm": "^2.0.0-16",
    "sails-hook-sockets": "^1.4.0",
    "@sailshq/connect-redis": "^3.2.1",
    "@sailshq/socket.io-redis": "^5.2.0",
    "@sailshq/lodash": "^3.10.3",
    "async": "2.0.1",
    "@angular/animations": "^5.2.0",
    "@angular/common": "^5.2.0",
    "@angular/compiler": "^5.2.0",
    "@angular/core": "^5.2.0",
    "@angular/forms": "^5.2.0",
    "@angular/http": "^5.2.0",
    "@angular/platform-browser": "^5.2.0",
    "@angular/platform-browser-dynamic": "^5.2.0",
    "@angular/router": "^5.2.0",
    "core-js": "^2.4.1",
    "rxjs": "^5.5.6",
    "zone.js": "^0.8.19"
  },
  "devDependencies": {
    "@sailshq/eslint": "^4.19.3",
    "@angular/cli": "~1.7.4",
    "@angular/compiler-cli": "^5.2.0",
    "@angular/language-service": "^5.2.0",
    "@types/jasmine": "~2.8.3",
    "@types/jasminewd2": "~2.0.2",
    "@types/node": "~6.0.60",
    "codelyzer": "^4.0.1",
    "jasmine-core": "~2.8.0",
    "jasmine-spec-reporter": "~4.2.1",
    "karma": "~2.0.0",
    "karma-chrome-launcher": "~2.2.0",
    "karma-coverage-istanbul-reporter": "^1.2.1",
    "karma-jasmine": "~1.1.0",
    "karma-jasmine-html-reporter": "^0.2.2",
    "protractor": "~5.1.2",
    "ts-node": "~4.1.0",
    "tslint": "~5.9.1",
    "typescript": "~2.5.3"
  },

使用npm scripts进行构建

当我运行yarn start时,我希望能够同时运行sails lift和ng build,让它们并行运行。

本次我们将使用npm-run-all工具。

$> yarn add npm-run-all -D

使用这个命令可以同时进行构建和启动服务器,使得在执行”yarn start”时两者同时进行。

"scripts" : {
...
    "start:dev": "npm-run-all --parallel lift:dev build:dev",
    "build:dev": "ng build --watch --output-path=./assets/dist --base-href=/ --deploy-url=/dist/",
    "lift:dev": "sails lift",
    "inspect:dev" : "sails inspect",
...
}

我会将其设置成这种感觉。

補充:關於build:dev選項

关于传递给 ng build 命令的参数。

–output-path用于定义将构建生成的成果物输出到何处。

–base-href定义了Router将识别为根路径的位置。 在这种情况下,Angular的Router将根路径设置为实际URL上的“ / ”,即在名义上和实际上都将其作为根路径设置。

–deploy-url用于定义部署的位置在哪里。
在这里使用”/dist/”的意图是,从Angular应用程序的角度看,资产(如main.bundle.js和每个组件定义的css等)实际上并不直接放置在Sails服务器上的资产目录中,而是放置在构建Angular应用程序的成果物目录中(即Sails资产文件夹的子文件夹assets/dist)。
如果不这样做,Angular端所请求的资产将全部不存在,导致页面无法正确打开。

使用Sails的模板引擎将Angular的index.html包含进来。

暫時先將 qiita_sails/views/pages 目錄下的 homepage.ejs 檔案以以下內容進行替換。

<!DOCTYPE html>
<html>

<!-- webpack generate html -->
<%- partial('../../assets/dist/index.html') %>

</html>

这就是所有的内容。

接下来,让我们试着移动屏幕。

确认画面!

$> yarn start:dev

让我们来看一下。

当然也要进行E2E移植。

将qiita_angular/e2e迁移到qiita_sails/e2e。
然后,将protractor.conf.js文件放置在qiita_sails下。
为了编译,将放在assets/下的tsconfig.json文件也复制到qiita_sails中。

我只会将protractor.conf.js中的baseUrl更改。

baseUrl: 'http://localhost:1337/',

这种情况下

ng e2e

然后,我认为您会发现测试像上一次那样成功。

连接Angular服务和Sails API

好吧,只剩下与API连接了。
继续努力吧。

我们来处理assets/angular/app/qiita(q深啊…)的qiita.service.ts。

将HttpClient进行依赖注入

我会先将HttpClient注入进来。

import { HttpClient } from '@angular/common/http';

@Injectable()
export class QiitaService {

  constructor(private http:HttpClient) { }

在app.module.ts中导入包含HttpClient的模块。


...
import { HttpClientModule } from '@angular/common/http';


@NgModule({
...
  imports: [
...
    HttpClientModule, // 足す。
...
  ],
  providers: [  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

暂时来说,在这种情况下

ng e2e

挺好的。

我想提出请求

只需要修改原本已经写好的Promise代码中的resolve段落。

  public async load(id:number):Promise<any> {
    return new Promise((resolve,reject) => {
      this.http.get('/blog/' + String(id)).subscribe(
      data => resolve(data),
      error => reject(error)
      );
    });
  }

  public async register(blog:any):Promise<any> {
    return new Promise((resolve,reject)=>{
      this.http.post('/blog',blog).subscribe(
        data => resolve(data),
        error => reject(error)
        );
    });
  }

其实仔细考虑的话,从一开始就返回Observable也是可以的…

暂时保持这个状态

ng e2e

你要做好了吗?

暂时就是这样了。

总结

    • @angular/cliでコンポーネントを作成すると便利。

 

    • Sails側のアセットフォルダにAngularのソースを入れとく。

 

    • Sailsのサーバーが起動するときにAngular側のビルドを並行して走らせる。

 

    Angularのindex.htmlをSailsのテンプレートエンジンでインクルードすれば万事OK!
广告
将在 10 秒后关闭
bannerAds