📜  评论刀片 laravel - TypeScript (1)

📅  最后修改于: 2023-12-03 15:12:09.309000             🧑  作者: Mango

评论刀片 Laravel - TypeScript

评论刀片是Laravel框架中非常有用的功能之一,它允许用户在网站上发布评论和回复,促进互动和交流。在这里,我们将介绍如何使用TypeScript和Laravel框架创建评论刀片。

前置知识

在继续本文之前,请确保您已经具备以下知识:

  • 熟悉Laravel框架的基本操作
  • 熟悉TypeScript的基本语法和概念
安装和配置

首先,我们需要安装TypeScript和typescript-ioc库。打开终端并输入以下命令:

npm install typescript typescript-ioc --save-dev

接着,我们需要在项目中创建一个TypeScript配置文件。在项目根目录下创建一个名为“tsconfig.json”的文件,并添加以下内容:

{
  "compilerOptions": {
    "lib": ["es2016", "dom"],
    "target": "es5",
    "noImplicitAny": false,
    "sourceMap": true,
    "outDir": "./dist"
  },
  "exclude": [
    "node_modules",
    "dist"
  ]
}

此配置文件将告诉TypeScript编译器如何编译我们的代码。

实现

现在,让我们来看看如何实现评论刀片。

1. 创建模型

首先,我们需要创建评论模型。在Laravel中使用以下命令生成模型:

php artisan make:model Comment

在生成的模型文件中,我们需要定义以下属性:

import { AutoWired, Singleton } from "typescript-ioc";

export interface CommentJson {
  id: number;
  content: string;
  author: string;
  parent_id?: number;
}

@Singleton
@AutoWired
export class Comment {
  private id: number;
  private content: string;
  private author: string;
  private parent_id?: number;

  constructor(commentJson?: CommentJson) {
    if (commentJson) {
      this.id = commentJson.id;
      this.content = commentJson.content;
      this.author = commentJson.author;
      this.parent_id = commentJson.parent_id;
    }
  }

  public toJson(): CommentJson {
    return {
      id: this.id,
      content: this.content,
      author: this.author,
      parent_id: this.parent_id,
    };
  }

  public getId(): number {
    return this.id;
  }

  public getContent(): string {
    return this.content;
  }
}

我们使用TypeScript的类定义了Comment模型,并将其导出为单例(使用typescript-ioc库)。我们还创建了一个包含对模型属性的getter和setter的构造函数,并创建了一个toJson方法将模型转换为JSON格式。

2. 创建迁移

接下来,我们需要创建迁移。使用以下命令:

php artisan make:migration add_comment_table

打开新创建的迁移文件,添加以下内容:

import { MigrationInterface, QueryRunner, Table } from 'typeorm';

export class CreateCommentsTable1619270433202 implements MigrationInterface {

    public async up(queryRunner: QueryRunner): Promise<void> {
        await queryRunner.createTable(new Table({
            name: 'comments',
            columns: [
                {
                    name: 'id',
                    type: 'integer',
                    isPrimary: true,
                    isGenerated: true,
                    generationStrategy: 'increment',
                },
                {
                    name: 'content',
                    type: 'text',
                },
                {
                    name: 'author',
                    type: 'varchar',
                },
                {
                    name: 'parent_id',
                    type: 'integer',
                    isNullable: true,
                },
            ],
        }), true);
    }

    public async down(queryRunner: QueryRunner): Promise<void> {
        await queryRunner.dropTable('comments');
    }

}

这会在数据库中创建一个名为“comments”的表,包含id、内容、作者和parent_id列。

3. 创建服务

接下来,我们需要创建一个用于处理评论的服务。在Laravel中使用以下命令创建服务:

php artisan make:service CommentService

在新创建的服务文件中,添加以下内容:

import { Injectable } from "typescript-ioc";
import { Comment } from "../models/Comment";
import { CommentJson } from "../models/Comment";
import { CommentRepository } from "../repositories/CommentRepository";

@Injectable
export class CommentService {
  constructor(private commentRepository: CommentRepository) {}

  public async findAll(): Promise<Comment[]> {
    const commentJsonList: CommentJson[] = await this.commentRepository.findAll();
    const comments = [];
    for (const commentJson of commentJsonList) {
      const comment: Comment = new Comment(commentJson);
      comments.push(comment);
    }
    return comments;
  }

  public async findById(id: number): Promise<Comment | null> {
    const commentJson: CommentJson | null = await this.commentRepository.findById(id);
    if (!commentJson) {
      return null;
    }
    const comment: Comment = new Comment(commentJson);
    return comment;
  }

  public async save(comment: Comment): Promise<void> {
    await this.commentRepository.save(comment);
  }
}

我们创建了一个注入CommentRepository的服务,并定义了一个查找所有评论的方法。该方法将通过注入的CommentRepository从数据库中检索评论,创建Comment对象,并将其返回。

我们还定义了一个findById方法来按id查找评论。

最后,我们定义了一个保存评论的方法,该方法将Comment参数保存到数据库中。这是从CommentRepository调用的简单方法。

4. 创建控制器

现在我们需要创建一个控制器来处理来自评论表单的数据,以及显示和回复评论。

在Laravel中使用以下命令创建控制器:

php artisan make:controller CommentController

然后打开新创建的控制器文件,并添加以下内容:

import { Controller, Get, Post, Req } from "@nestjs/common";
import { Request } from "express";
import { Comment } from "../models/Comment";
import { CommentService } from "../services/CommentService";

@Controller("comments")
export class CommentController {
  constructor(private commentService: CommentService) {}

  @Get()
  public async index() {
    const comments = await this.commentService.findAll();
    return { comments: comments.map((comment) => comment.toJson()) };
  }

  @Post("/")
  public async store(@Req() request: Request) {
    const commentContent: string = request.body.content;
    const commentAuthor: string = request.body.author;
    const commentParentId: number = request.body.parent_id ?? undefined;

    const comment: Comment = new Comment({
      content: commentContent,
      author: commentAuthor,
      parent_id: commentParentId,
    });
    await this.commentService.save(comment);

    return { success: true };
  }

  @Get(":id")
  public async show(id: number) {
    const comment: Comment | null = await this.commentService.findById(id);
    if (!comment) {
      return { comment: null };
    }
    const json = comment.toJson();
    return { comment: json };
  }
}

我们创建了一个注入CommentService的控制器,并定义了index、store和show方法。

  • index返回所有评论的Json格式
  • store创建一个新的评论,并将其保存到数据库中
  • show按id返回评论的Json格式
5. 创建视图

最后,我们需要创建一个视图来显示所有评论,并允许用户在页面底部添加新评论。

在Laravel中,我们将使用Blade模板引擎来创建视图。打开Laravel的主视图,并添加以下内容:

<html>
  <head>
    <style>
      .card {
        margin: 10px;
        padding: 10px;
        border: 1px solid #ccc;
        border-radius: 4px;
      }

      .card .author {
        font-size: 1.2rem;
        font-weight: bold;
      }

      .card .content {
        margin-top: 10px;
        font-size: 1.1rem;
        line-height: 1.3;
      }

      .card .reply-form {
        margin-top: 10px;
        display: none;
      }

      .card .reply-form.show {
        display: block;
      }

      .card .reply-form p {
        margin-top: 10px;
        margin-bottom: 0;
        font-weight: bold;
      }

      .card .reply-form textarea {
        margin-top: 10px;
        width: 100%;
        height: 100px;
        padding: 5px;
        border: 1px solid #ccc;
        border-radius: 4px;
      }

      .card .reply-form button {
        margin-top: 10px;
        background-color: #f7d573;
        color: #fff;
        font-weight: bold;
        border-radius: 4px;
        padding: 5px;
        border: none;
      }
    </style>
  </head>
  <body>
    <div id="app">
      <h1>Comments</h1>
      <div class="comment-form">
        <h3>Leave a comment</h3>
        <div class="form">
          <div class="field">
            <label>Your name</label>
            <input type="text" name="author" />
          </div>

          <div class="field">
            <label>Your comment</label>
            <textarea name="content"></textarea>
          </div>

          <div class="field">
            <button type="button" onclick="addComment()">Submit</button>
          </div>
        </div>
      </div>

      <div class="comments">
        <h3>Latest comments</h3>
        <div id="comments">
          @foreach ($comments as $comment)
          <div class="card">
            <div class="author">
              {{ $comment["author"] }}
              <a href="#" class="reply-toggle" onclick="showReplyForm({{ $comment["id"] }})">Reply</a>
            </div>
            <div class="content">{{ $comment["content"] }}</div>
            <form class="reply-form" onsubmit="replyComment(event, {{ $comment["id"] }})">
              <p>Reply to {{ $comment["author"] }}:</p>
              <textarea name="content"></textarea>
              <button type="submit">Submit</button>
            </form>
          </div>
          @endforeach
        </div>
      </div>
    </div>

    <script src="{{ asset('js/app.js') }}"></script>
  </body>
</html>

此视图包括一个包含“Leave a comment”的表单,以及最新评论的列表。每个评论都显示了评论者的姓名和评论内容。还添加了“Reply”链接,以启动回复表单。

总结

在本文中,我们了解了如何使用TypeScript和Laravel框架创建一个评论刀片。我们创建了一个评论模型、评论表单、一个服务、一个控制器和一个视图,并将它们集成在一起,使其能在网站上正常工作。如果您感兴趣,请继续探索TypeScript和Laravel的功能,以了解更多有用的技巧和技术。