Ruby
 Computer >> コンピューター >  >> プログラミング >> Ruby

Rails5でのAngularの使用

あなたは前にその話を聞いたことがあります。分散型で完全に機能するバックエンドAPIと、通常のツールセットで作成されたフロントエンドで実行されているアプリケーションがすでにあります。

次に、Angularに移動します。または、AngularをRailsプロジェクトと統合する方法を探しているだけかもしれません。これは、この方法を好むためです。私たちはあなたを責めません。

このようなアプローチを使用すると、両方の世界を活用して、たとえばRailsとAngularのどちらの機能を使用してフォーマットするかを決定できます。

構築するもの

心配する必要はありません。このチュートリアルは、この目的のために作成されました。ユーザーのドメイン上で完全に機能するCRUDアプリケーションの作成について詳しく説明します。

記事の最後で、Angularに関するいくつかの基本的な概念と、以下に示すように、フロントエンド用にAngularと直接統合するRailsバックエンドプロジェクトをセットアップする方法を学習します。

Rails5でのAngularの使用 RailsとAngularで作成されたユーザーのCRUD

このアプリケーションは、外部の偽のテストWebサービスから取得したユーザーのドメインで4つのCRUD操作をすべて処理します。アプリはMVCアーキテクチャ上に構築され、各Angularレイヤーが詳細に説明されているため、物事がどのように結びついているかをよりよく理解できます。スタイルはBootstrap次第です。

セットアップ

ご想像のとおり、次のソフトウェアが必要になります。

  • ルビー(バージョン2.7.0preview1を選択しました)
  • Ruby and Rails(私はバージョン5.0.7.2を使用しています)
  • Node.js(v13.7.0を使用します)
  • ヤーン(少なくともそのバージョン1.22.4)

すべてが正しくインストールされていることを確認してください。次に、プロジェクトに進むことができます。好みのフォルダを選択して、次のコマンドを実行します:

rails new crud-rails-angular

セットアップが完了するのを待ち、お気に入りのIDE内でプロジェクトを開きます。この記事では、VS Codeを使用します。これは、シンプルで強力であり、RailsとAngularの両方の構文をスムーズに採用しているためです。

Rails 5をしばらく使用している場合は、そのnewに気付いたかもしれません。 コマンドはGemfile内にバグを生成します SQLite構成の場合。最小バージョンがないため、エラーが発生します。この問題をに更新して修正しましょう

gem 'sqlite3', '~> 1.3.10'

完璧です!

Webpackerのセットアップ

RailsでJavaScriptのようなアプリケーションを管理する最良の方法は、Webpackerを使用することです。 Webpackを舞台裏で利用して、前処理やAngularなどのJavaScriptアプリを既存のRailsアプリケーションにバンドルするなどの機能を提供します。

インストールするには、Gemfileに新しい行を追加するだけです。 :

gem 'webpacker', '~> 4.3.x'

これにより、最新バージョンを確実にインストールできます。次に、次のコマンドを実行します。

bundle install
bundle exec rake webpacker:install
bundle exec rake webpacker:install:angular

最初のコマンドは、追加されたRailsの依存関係をダウンロードして更新します。

2つ目は、npm installと同等です。 node_modulesを作成するため フォルダを作成し、Babel、Sass、Browserlist、Webpackなどの必要なAngular依存関係をインストールします。これで、同じプロジェクトにNodeアプリとRailsアプリの両方が含まれるようになりました。

最新のコマンドでは、npm install angularと同等のものがあります 、Angularに必要なすべての依存関係をダウンロードし、Railsプロジェクトと連携して機能させます。

これらのコマンドの最後に、 package.jsonも表示されます。 ファイルが作成されました。必要な依存関係はすべてそこに配置されており、将来必要なものを追加できます。

また、一部のフォルダとファイルは / appの下に作成されました 新しい/javascriptなどのフォルダ 。このフォルダーには、すでに / hello_angularがあります。 開発の開始をサポートするために作成されたフォルダ。

時間を確保するために、フォルダとファイルの構造を次のようにミラーリングするようにお願いします。

Rails5でのAngularの使用

いくつかの角度調整

Webpackerは、生成されたRailsプロジェクト内で一連の調整を行うことをお勧めします。それでは、家を整理するために少し時間をかけましょう。

まず、 application.jsを開きます / packsの下に配置されたファイル フォルダ(上の図に表示)を追加し、次のコードを追加します:

import "core-js/stable";
import "regenerator-runtime/runtime";

これらのインポートは、Railsプロジェクト内のJavaScript環境を安定させるための補助的な力として機能します。

次に、ページへの出力を選択する必要がある場所からRailsに通知する必要があります。 Webpackerが荷物の梱包を完了すると、Railsが認識しなければならない配布可能な静的ファイルの束が生成されます。

application.html.erbに移動します app / views / layoutの下のファイル フォルダを作成し、その<head>を変更します コンテンツに次のタグを付けます:

<head>
  <title>CrudRailsAngular</title>
  <base href="/" />
  <!-- 1 -->
  <%= csrf_meta_tags %> <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous" />
  <!-- 2 -->
  <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %> <%= javascript_pack_tag 'application' %>
  <!-- 3 -->
</head>

これを少し分解してみましょう:

  1. ここでは、baseを追加します タグ。アプリケーションの起動時にどこを見ればよいかをRailsに指示します。
  2. Bootstrapを使用してページのスタイルを推測するため、実装のみに集中できます。
  3. ここに、 / packsにマップするWebpackerタグを配置する必要があります。 フォルダの内容(コンパイルのたびにWebpackerによって自動生成されるものと同じです)。
モデルとデータベース

データベースの設定に進みます。処理を高速化するために、Userという新しいモデルの足場を作成します。 。これは、それを達成するために実行する必要のあるコマンドです:

rails g scaffold User name:string age:integer address:text && rake db:migrate

モデルのすべてのフォルダとファイルが作成されます。これらは、Railsに(SQLiteからの)データベース情報を操作させ、CRUD操作に保存するために必要です。

次に、新しいファイル XXX1_create_users.rb が表示されます。 db / migrate /の下に作成されました フォルダ。それを開くと、新しく作成されたCreateUsersが表示されます 記録します。

app / models /内 フォルダには、その時点で作成されたUserが表示されます user.rbのモデル ファイル。

次に、 db / seeds.rbを開きます。 ファイルを作成し、次のコードを追加します:

User.create(name: 'Luke Wan', age: 23, address: '123 Test St.')
User.create(name: 'Mary Poppins', age: 41, address: '123 ABC St.')
User.create(name: 'John Neilman', age: 76, address: '000 Test St.')

このコードは、Usersを初期化します 起動時にいくつかのデータを含むテーブル。保存して、次のコマンドを実行します:

rake db:seed

これにより、上記のコマンドを使用してテーブルがシードされます。次に、SQLiteデータベースに入り、次のコマンドを発行して、それが機能したかどうかを確認できます。

sqlite3 db/development.sqlite3

次に、テーブルデータを選択します:

select * from users;

結果が表示される場合があります。

ユーザーコンポーネント

HTMLとCSSをRailsページに変換するために、さらにいくつかの依存関係をインストールする必要があります。 Angularルーター、forms libs、およびngx-bootstrapを追加します。これらは、Bootstrapコンポーネントの作成と操作を容易にするために使用します。したがって、次のコマンドを発行します。

yarn add @angular/router @angular/forms html-loader css-loader ngx-bootstrap

ただし、コンポーネントコードに入る前に、Angularコンポーネントの構造から始めて、指摘する必要のある重要な概念がいくつかあります。

コンポーネントとは何ですか?

Angularには、ビューをTypeScriptで作成されたアプリケーションロジックに接続するためのコンポーネントが存在します。

つまり、コンポーネントは、ビューがその機能をサポートするために必要なすべてのロジックのコンテナーのようなものです。ビューが提示する値を定義し、それらのフローを制御します。これは、同様のフレームワークの「コントローラー」に相当します。

コンポーネントを作成するには、新しいクラスを定義し、OnInitを実装するだけです。 インターフェイスを作成し、クラスに@Componentでアノテーションを付けます デコレータ:

export class UserIndexComponent implements OnInit {
    constructor() { ... }

    ngOnInit() { ... }
}

@ComponentとOnInit

@Component デコレータは、このクラスを認識可能なAngularコンポーネントとしてマークし、実行時の処理、インスタンス化、および使用に関してAngularがそれらを処理するのに役立つメタデータ構成を提供するため重要です。

次のメタデータ構成を取得します。

@Component({
    selector: "users",
    template: templateString,
})

ここでは、selector 提供された値が、現在のディレクティブをテンプレートに識別するために使用できるCSSセレクターであることをAngularに通知します。はい、それは次のメタデータプロパティで提供されるものと同じテンプレートです。

OnInit ただし、インターフェイスはオプションであり、コンポーネントがライフサイクルを終了する前に初期化するのに適した方法です。構築後の方法のように機能します。

依存性注入

AngularはDI(依存性注入)です )フレームワーク、モジュール性と生産性を向上させる特性。

Angularの依存関係は、サービスやリポジトリから、コード内の別の場所に注入するのに適していると思われるあらゆる種類の通常のオブジェクトまでさまざまです。

クラスを「注入可能」にするには、@Injectableで注釈を付けるだけです。 デコレータ:

@Injectable({
    providedIn: "root",
})
export class UserService {
    ...
}

providedIn 作成している注射剤を提供する注射器を示します。 root 値は、インジェクターがアプリケーションレベルのものでなければならないことをAngularに伝えます。ここで確認できることは他にもあります。

たとえば、クラスをコンポーネントに注入するには、Angularにコンポーネントのコンストラクターで注入するように依頼します。

constructor(
    private userService: UserService,
) {}

とても簡単です!

完成したコンポーネント

以下に、ユーザーコンポーネントの最終的なコードリストを示します。 index.component.tsに配置します 、 javascript / hello_angular / app /の下 フォルダ。

import { Component, OnInit, TemplateRef } from "@angular/core";
import { FormGroup, FormBuilder } from "@angular/forms";
import { BsModalRef, BsModalService } from "ngx-bootstrap/modal";

import templateString from "./index.component.html";
import { UserService } from "../user.service";
import { User } from "../user.class";

@Component({
  selector: "users",
  template: templateString,
})
export class UserIndexComponent implements OnInit {
  users: User[];
  modalRef: BsModalRef;
  userForm: FormGroup;
  isNew: Boolean;

  constructor(public fb: FormBuilder, private userService: UserService, private modalService: BsModalService) {}

  public newUser(template: TemplateRef<any>) {
    this.reset();
    this.modalRef = this.modalService.show(template);
  }

  public createUser() {
    this.userService.create(this.userForm.value).subscribe(() => {
      console.log("User created!");
      this.reset();

      this.modalRef.hide();
    });
  }

  public editUser(user, template: TemplateRef<any>) {
    this.isNew = false;
    this.userForm = this.fb.group({
      id: [user.id],
      name: [user.name],
      age: [user.age],
      address: [user.address],
    });

    this.modalRef = this.modalService.show(template);
  }

  public updateUser() {
    const { id } = this.userForm.value;
    this.userService.update(id, this.userForm.value).subscribe(() => {
      console.log("User updated!");
      this.reset();

      this.modalRef.hide();
    });
  }

  public deleteUser(id) {
    if (confirm("Are you sure?")) {
      this.userService.delete(id).subscribe(() => {
        console.log("User deleted!");
        this.reset();
      });
    }
  }

  ngOnInit() {
    this.reset();
  }

  public reset() {
    this.isNew = true;
    this.userService.getUsers().subscribe((users) => {
      this.users = users;
    });

    this.userForm = this.fb.group({
      id: [""],
      name: [""],
      age: [""],
      address: [""],
    });
  }
}

Users 配列は、画面にリストされ、resetから取得された現在のテーブルデータを保持します 次に、UserServiceを介してRailsAPIを呼び出すメソッド (作成予定)

userForm 両方の操作で同じフォームが使用されるため、これはユーザーの作成と更新に役立つ単なるリファレンスです。 isNew また、それを支援し、現在どのフローにいるのかを特定します。

ここでは、各操作に対してCRUDと同等のメソッドがあります。それぞれがそれぞれのUserServiceを呼び出します RailsAPIでプロセスをコミットするメソッド。

また、テンプレートをHTMLに変換するためにHTMLモジュールを設定する必要があります(モジュールについてはすぐに詳しく説明します)。したがって、 html.d.tsを開きます 同じフォルダ内にファイルを追加して追加します:

declare module "*.html" {
  const content: string;
  export default content;
}
角度サービスとモデル

AngularのUserServiceに移りましょう 作成。 Angularは、Railsと同じようにフレームワークです。つまり、たとえば、モデルが重複している(または非常に類似している)場合でも、ルールに従うことができます。

モデルとは何ですか?

角度モデルは、一緒に意味のあるデータ属性を保持する単純なオブジェクトです(つまり、ドメインの簡潔な部分を表します)。これらは、ほとんどの言語とフレームワークの他のモデルとまったく同じです。

ユーザーのモデルのようにデータをコード全体に複製するのではなく、データを1か所に集中させると非常に役立ちます。

export class User {
  constructor(public id: number, public name: string, public age: number, public address: string) {}
}

TypeScriptであることに注意してください。したがって、モデルの属性には常に型が定義されている必要があります。

user.class.tsという名前の新しいファイルを作成します javascript / hello_angular / app / user /の下 フォルダを作成し、上記のコードをその中に配置します。

サービスはどうですか?

サービスは広い概念ですが、明確に定義された目的のあるオブジェクトとして理解できます。これらは、より複雑なロジックでコンポーネントを支援し、通常は外部サービスまたはデータベースからの処理および変換されたデータをコンポーネントに提供します。

サービスには特定のアノテーションやインターフェースは必要ありません。クラスを作成して注入可能にするだけです 、前に見たように。次に、それをコンポーネントに注入できます。

監視可能なサービス

Angularのもう1つの興味深い機能は、クラスでRxJSを使用できることです。

たとえば、AngularのデフォルトのHTTPクライアントは、外部サービスから情報をフェッチするために使用するものと同じであり、RxJS Observablesを返します。 。これが、UserServiceのいずれかを呼び出すときに発生する理由です。 ユーザーコンポーネント内のメソッドでは、subscribe Observableに 結果:

this.userService.getUsers().subscribe((users) => {
  this.users = users;
});

RxJSに慣れていない場合は、そのドキュメントを簡単に読むことを強くお勧めします。それほど難しいことではありません!;)

繰り返しますが、 javascript / hello_angular / app / user / フォルダに、 user.service.tsという別のファイルを作成します 。これがその内容です:

import { Injectable } from "@angular/core";
import { HttpClient, HttpHeaders } from "@angular/common/http";
import { map } from "rxjs/operators";
import { Observable } from "rxjs";

import { User } from "./user.class";

@Injectable({
  providedIn: "root",
})
export class UserService {
  constructor(private http: HttpClient) {}

  httpOptions = {
    headers: new HttpHeaders({
      "Content-Type": "application/json",
    }),
  };

  getUsers(): Observable<User[]> {
    return this.http.get("/users.json").pipe(
      map((users: User[]) =>
        users.map((user) => {
          return new User(user.id, user.name, user.age, user.address);
        })
      )
    );
  }

  create(user): Observable<User> {
    return this.http.post<User>("/users.json", JSON.stringify(user), this.httpOptions);
  }

  update(id, user): Observable<User> {
    return this.http.put<User>("/users/" + id + ".json", JSON.stringify(user), this.httpOptions);
  }

  delete(id) {
    return this.http.delete<User>("/users/" + id + ".json", this.httpOptions);
  }
}

これと先ほど作成したコンポーネントの類似点を見つけられますか?これは、コンポーネント内の操作をサポートするために対応する操作が必要なためです。

HttpClientに注意してください クラスのコンストラクター内にも注入する必要があるため、クラスと一緒に使用できます。

各操作は、自動生成されたRailsAPIへのHTTP呼び出しを行います。

ビュー

Angularはビューのテンプレートで動作します。テンプレートは、Angularに各コンポーネントのレンダリング方法を指示する一種の階層的なHTMLとJavaScriptの組み合わせです。

ただし、ビューの構築を進める前に、まずAngularがテンプレートシステムをどのように分割するかを理解しましょう。

角度ディレクティブ

Angularテンプレートは基本的に動的であるため、一部のディレクティブ Angularを正しい方法でレンダリングするために必要です。

ディレクティブは、@Directiveを持つ単なるクラスです。 コンポーネントのようなデコレータ。はい、@Component @Directiveから継承 、したがって、これも正式に指令です。

ただし、他に2つのタイプがあります。構造 および属性 ディレクティブ。

構造ディレクティブ

これらのディレクティブは、JavaScriptからAngularテンプレートに変換された条件付きおよびループ構造を表します。それらは、バニラJavaScriptコード内でプログラミングしている場合のように、テンプレートを可能な限り動的にするのに役立ちます。次の例を見てください:

<tr *ngFor="let user of users">
  <td>{{ user.name }}</td>
</tr>

*ngFor ディレクティブは、Angularにusersの配列を反復処理するように指示します 各ユーザーの名前をDOMに出力します。

属性ディレクティブ

これらは、要素の外観または動作と直接連携します。次の例を見てください:

<form [formGroup]="userForm" (ngSubmit)="isNew ? createUser() : updateUser()" novalidate></form>

ここでは、フォームのsubmitを条件付きで設定することにより、フォームの動作を変更しています。 関数とAngularのFormGroupの利用 各フォーム入力をデータバインドします。

データバインディング

Webフレームワークを使用してフォームを作成することは、データバインディングを提供しない場合、トリッキーでエラーが発生しやすいタスクになる可能性があります。

Angularは双方向のデータバインディングをサポートしています。つまり、テンプレートの一部をコンポーネントに直接接続したり、その逆を行ったりすることができます。

上記のフォームは、FormGroupの良い例です。 データバインディングパワー。各フォームフィールドをuserFormに自動的にバインドします コンポーネント内に作成されたオブジェクト。

editUserで たとえば、メソッドでは、userFormという反対のバージョンのバインディングを確認できます。 の値はコンポーネント内で設定され、ビューのフォームを反映する必要があります。

インデックスビューの構築

index.component.htmlのコンテンツを分類してみましょう 2つの部分に。これは最初のものです:

<div class="container pricing-header px-3 py-3 pt-md-5 pb-md-4 mx-auto text-center">
  <h1 class="display-4">User's Listing</h1>
  <p class="lead">A quick CRUD example of how to integrate Rails with Angular</p>

  <table class="table">
    <tr>
      <th>Id</th>
      <th>Name</th>
      <th>Age</th>
      <th>Address</th>
      <th>Actions</th>
    </tr>

    <tbody>
      <tr *ngFor="let user of users">
        <td>{{ user.id }}</td>
        <td>{{ user.name }}</td>
        <td>{{ user.age }}</td>
        <td>{{ user.address }}</td>
        <td colspan="2">
          <button class="btn btn-secondary" (click)="editUser(user, template)">Edit</button>
          |
          <button class="btn btn-danger" (click)="deleteUser(user.id)">Delete</button>
        </td>
      </tr>
    </tbody>
  </table>

  <button class="btn btn-primary float-right mt-4" (click)="newUser(template)">Insert New</button>
</div>

そのほとんどはプレーンHTMLで構成されています。 Bootstrapクラスについては詳しく説明しません。

ここで重要なのはngForです。 テーブルの行のディレクティブ。 usersを反復処理するのに役立ちます 配列(覚えていますか?){{ … }}を介してHTML出力に各属性を出力します オペレーター。

onClick のように、DOMイベントの1つを追加したいときはいつでも 、イベント名を括弧で囲み、クリックしたときに呼び出すコンポーネント関数を追加するだけです。

モーダルビューの構築

2番目の部分はモーダルコンテンツに関連しているため、前の部分の下に追加します。

<ng-template #template>
  <div class="modal-header">
    <h4 class="modal-title pull-left">{{ isNew ? "New User" : "Update User" }}</h4>
    <button type="button" class="close pull-right" aria-label="Close" (click)="modalRef.hide()">
      <span aria-hidden="true">&times;</span>
    </button>
  </div>
  <div class="modal-body">
    <form [formGroup]="userForm" (ngSubmit)="isNew ? createUser() : updateUser()" novalidate>
      <input type="hidden" formControlName="id" class="form-control" />
      <div class="form-group">
        <label>Name</label>
        <input type="text" formControlName="name" class="form-control" />
      </div>
      <div class="form-group">
        <label>Age</label>
        <input type="text" formControlName="age" class="form-control" />
      </div>
      <div class="form-group">
        <label>Address</label>
        <textarea class="form-control" formControlName="address" rows="3"></textarea>
      </div>

      <button type="submit" class="btn btn-primary">Submit</button>
    </form>
  </div>
</ng-template>

<ng-template>を使用していることに注意してください タグ。HTMLとAngularの間に要素を固定できます。テンプレートIDは、#の直後にあります サイン。

フォーム内で、isNewを使用していることにも注意してください このフォームの現在の使用法がユーザーの作成または更新に関連しているかどうかを確認するためのコンポーネント変数。

最後に、 hello_angular全体を注入する必要があります Railsへのアプリケーションindex.html.erb ページ。したがって、このファイルを views / users /の下で開きます。 フォルダを作成し、その内容を次のように変更します。

<hello-angular>We're almost done...</hello-angular> <%= javascript_pack_tag 'hello_angular' %>
角度モジュール

ここで、Angularにどこで情報を見つけるかを指示する必要があります。モジュールの構成内で発生します。

app-bootstrap.module.tsにコンテンツを追加することから始めましょう :

import { NgModule } from "@angular/core";
import { CommonModule } from "@angular/common";

import { ModalModule } from "ngx-bootstrap/modal";

@NgModule({
  imports: [CommonModule, ModalModule.forRoot()],
  exports: [ModalModule],
})
export class AppBootstrapModule {}

これは、ngx-bootstrapから継承しているBootstrapコンポーネントに制限されています。現在使用している唯一のコンポーネントは、ブートストラップモーダルです。

次に、 app-routing.module.tsを開きます ファイルを作成し、その内容を次のように変更します。

import { RouterModule, Routes } from "@angular/router";
import { NgModule } from "@angular/core";

import { UserIndexComponent } from "./user/index/index.component";

const appRoutes: Routes = [
  { path: "users", component: UserIndexComponent },
  { path: "", redirectTo: "/users", pathMatch: "full" },
];

@NgModule({
  imports: [RouterModule.forRoot(appRoutes, { scrollPositionRestoration: "enabled" })],
  exports: [RouterModule],
})
export class AppRoutingModule {}

これにより、 / users のときに、Angularが適切なユーザーのコンポーネントと一致するようになります。 パスが呼び出されます。

そして最後に、それらすべてをメインのAppModule内に登録します クラス。 app.module.tsを開きます ファイルを作成し、次のようになっていることを確認します:

import { BrowserModule } from "@angular/platform-browser";
import { NgModule } from "@angular/core";
import { HttpClientModule } from "@angular/common/http";
import { FormsModule, ReactiveFormsModule } from "@angular/forms";

import { AppComponent } from "./app.component";
import { AppRoutingModule } from "./app-routing.module";
import { AppBootstrapModule } from "./app-boostrap.module";
import { UserIndexComponent } from "./user/index/index.component";

@NgModule({
  declarations: [AppComponent, UserIndexComponent],
  imports: [HttpClientModule, AppRoutingModule, BrowserModule, FormsModule, ReactiveFormsModule, AppBootstrapModule],
  providers: [],
  bootstrap: [AppComponent],
})
export class AppModule {}

ここでは、すべてがマッピングされています。フォームから、HTTPクライアントとユーザーコンポーネントからBootstrapモジュールの構成、ルーティングまで。

構成の終了

テストに入る前に、 app.component.tsから始めていくつかの作業を完了する必要があります。 ファイル:

import { Component } from "@angular/core";

@Component({
  selector: "hello-angular",
  template: "<router-outlet></router-outlet>",
})
export class AppComponent {
  name = "Angular!";
}

メインのアプリコンポーネントはパスをルーティングする方法を知っている必要があるため、RouterOutletがその役割を果たします。

次に、Webpackerがこれまでに使用しているHTML拡張機能を理解していることを確認する必要があります。これを行うには、 webpacker.ymlを開きます ファイルと、 / configの下 フォルダで、拡張機能を検索します セクションを作成し、次の項目を追加します:

- .html

Webpackerは、Angularにデフォルトで付属している組み込みのTypeScriptローダーのみを認識します。 HTMLを処理する必要があるため、以前に html-loader をインストールしました 依存。設定するには、 environment.jsを開きます config / webpackの下にあるファイル フォルダーを作成し、次のローダー構成を追加します。

environment.loaders.append("html", {
  test: /\.html$/,
  use: [
    {
      loader: "html-loader",
      options: {
        minimize: true,
      },
    },
  ],
});

最後に、AngularサービスがHTTP呼び出しでエラーを受け取らないようにするには、Railsによって実行されるCSRFトークンチェックを無効にする必要があります。このためには、 application_controller.rbを開きます app / controllersの下にあるファイル フォルダを作成し、その内容を次のように変更します。

class ApplicationController < ActionController::Base
  protect_from_forgery with: :null_session
end
テスト

それでおしまい!セットアップには多くのカスタマイズが必要なため、少し注意が必要ですが、結果はそれだけの価値があります。

テストするには、すべてを保存し、rails sを発行してサーバーを起動します コマンド。

次に、Webブラウザーに移動して、アドレスhttp:// localhost:3000/usersを入力します。さあ、CRUDWebアプリケーションを試してみてください。

結論

このCRUDを稼働させるのは長い道のりでした。最初のトライアルの後、将来のプロジェクトで物事が簡単になることがわかります。このプロジェクトが、両方の技術者に参加してプロジェクトを迅速に開始したい人のための出発点を設定するのに役立つことを願っています。

それを支援するオープンソースの足場プロジェクトはありませんが、そのような資料を用意するためにお互いの努力に依存しています。今ではあなたの番です;プロジェクトをフォークして(または最初から作成して)、カスタマイズを開始します。

この例のGitHubリポジトリはここにあります。楽しんでください!


  1. RailsでのHotwireの使用

    JavaScriptコードを記述せずに、ページの変更とフォームの送信を高速化し、複雑なページをコンポーネントに分割する方法を探している場合、この投稿はRailsをHotwireで次のレベルに引き上げるのに役立ちます。この記事では、サーバー側のレンダリングにツールを使用する方法を説明します。 Hotwireとは何ですか? Hotwireは、JSONの代わりにHTMLをネットワーク経由で送信することにより、JavaScriptを記述せずに最新のWebアプリケーションを構築する方法を提供します。これにより、ページの読み込みが速くなります。 Railsは、従来のシングルページアプリケーション(SP

  2. RailsでのTailwindCSSの使用

    CSSは魔法のようですが、時間がかかります。美しく、機能的で、アクセスしやすいサイトを使用するのは楽しいことですが、独自のCSSを作成するのは大変です。 Bootstrapなどの多くのCSSライブラリは近年爆発的に増加しており、Tailwindは2021年にパックをリードしています。 RailsにはTailwindが付属していませんが、この記事では、TailwindCSSを新しいRubyon Railsプロジェクトに追加する方法を説明します。これにより、設計の実装にかかる時間を節約できます。また、Tailwindのユーティリティクラスを使用した設計のウォークスルーも行います。このチュートリア