使用Visual Studio 2017创建React项目

976 篇文章 45 订阅
217 篇文章 4 订阅

Visual Studio 2017中设置React项目

我过去曾多次在工作要求中找到“React”并在Angular中进行开发,我总是想知道这两个单页应用程序框架有多么不同。好吧,我想我等不及了,在一次面试中,他们让我开发一个简单的React页面。我感到很惊讶,但我们不应该在面试中说我不能

首先要提到的是项目定义,如下所示:使用React创建一个带有汽车零件输入表单的简单单页应用程序。

  1. 汽车零件表单必须包含以下字段
      1. ID(唯一标识符,可以自动生成)。
      2. 部件号(从00001开始的随机5位数字)。
      3. 零件名称(汽车零件名称)。
      4. 描述(描述汽车部件)。
      5. 汽车制造商名称(克莱斯勒,道奇,福特等)
  2. 应用程序必须能够将汽车零件条目保存到数据库
  3. 应用程序必须能够编辑汽车零件条目
  4. 应用程序必须能够删除汽车零件条目

为了完成项目,我决定使用Visual Studio 2017,并在考虑这些要求的情况下探索React框架。幸运的是,互联网在任何主题中都提供了无数的资源。所以按步骤我进行如下:

创建一个React项目

这是任何.NET开发人员都知道的一个步骤。但过程如下:

  1. 打开Visual Studio 2017并选择创建新项目
  2. 在弹出窗口中选择项目类型,在本例中为ASP.NET Core Web Application。这是.NET Core模板组的一部分。
  3. 选择项目的文件夹位置,指定项目名称(React Demo)和解决方案名称(React Demo)。
  4. 检查创建解决方案目录选项。
  5. 如果您有一个GIT帐户,并且您希望将此项目保留在GIT中,那么也要检查该选项。
  6. 单击确定后,下一个窗口将显示不同的项目模板。选择ReactJS模板,然后单击确定
  7. 第一个窗口应该是这样的。第二个窗口非常简单,所以我没有在这里显示它,但它需要选择ReactJS选项并单击确定。

https://www.codeproject.com/KB/applications/1271257/fig1.png

解决方案资源管理器将是这样的:

https://www.codeproject.com/KB/applications/1271257/fig2.png

这是我们在运行项目时得到的:

https://www.codeproject.com/KB/applications/1271257/fig3.png

好吧!一个错误。如果我们选择项目名称并单击显示所有文件,我们将注意到没有node_modules文件夹。因此,我们的第一步是在项目文件级别打开命令提示符并运行NPM Install。第二次我们运行项目...... 搞定了!

https://www.codeproject.com/KB/applications/1271257/fig4.png

对于一个我们可能不需要的额外内容的项目来说,这是一个很好的起点。在我们的例子中,我们不需要CounterFetch Data菜单项和相关页面。我们需要首页,但我们可能需要更改该文本。为了提交React演示,我决定将主页中的文本替换为项目要求。结果将是这样的:

import * as React from 'react';
import { RouteComponentProps } from 'react-router';
 export class Home extends React.Component<RouteComponentProps<{}>, {}> {
   public render() {
       return <div>
           <h1>React Demo</h1>
           <p><u>Tasks:</u></p>
           <p>Make a simple one-page application with a car part entry form.</p>
           <p>Car part entry form must have the following fields:</p>
           <ul>
               <li>ID (unique identifier, can be automatically generated).</li>
               <li>Part Number (random 5-digit number starting with 00001.</li>
               <li>Part name (name of car part. </li>
               <li>Description (describe the car part).</li>
               <li>Car Manufacturer Name (Chrysler, Dodge, Ford, etc.)</li>
           </ul>
           <p>App must be able to save the car part entries to a database</p>
           <p>App must be able to edit car part entries</p>
           <p>App must be able to remove car part entries</p>
       </div>;
   }
}

我还决定删除CounterFetch Data并添加React Demo。第一步是一个简单的步骤,只打开Home.tsx文件并替换文本。第二步需要您打开NavMenu.tsx文件。在该文件中删除以下行:

<li>
     <NavLink to={ '/counter' } activeClassName='active'>
         <span className='glyphicon glyphicon-education'></span> Counter
     </NavLink>
</li>
<li>
     <NavLink to={ '/fetchdata' } activeClassName='active'>
         <span className='glyphicon glyphicon-th-list'></span> Fetch data
     </NavLink>
 </li>

并用以下代码替换它们:

<li>
    <NavLink to={ '/reactdemo' } activeClassName='active'>
         <span className='glyphicon glyphicon-education'></span> React Demo
    </NavLink>
</li>

同样在routes.tsx文件中删除counterfetchdata路由,并将其替换为“carpart”路由,如下所示:

import * as React from 'react';
import { Route } from 'react-router-dom';
import { Layout } from './components/Layout';
import { Home } from './components/Home';;
import { CarPart } from './components/ CarPart;
export const routes = <Layout>
   <Route exact path='/' component={ Home } />
   <Route path='/ carpart component={ CarPart } />
</Layout>;

我们可以删除Counter.tsxFetchData.tsx并添加一个新的carPart.tsx。要添加carPart tsx文件,我刚仅添加一个typescript文件,并将其扩展名更改为tsx。以下代码显示了CarPart组件的详细信息。

此组件有两个事件方法HandleSaveHandleDelete,单击相应按钮时会触发这些方法。我们在这些方法中需要注意的是react Fetch的调用。在HandleSave的情况下,它包含头数据并将对象作为头的一部分作为JSON对象传递,这样,在控制器中,SavePartData方法中CarPartModel类型的参数carPart将使用[FromModel]进行修饰,这意味着没有必须映射任何东西来传递和对象实例。

HandleDelete的情况下,唯一需要的参数是将从数据库中删除的部件ID

import 'bootstrap/dist/css/bootstrap.min.css';
import * as React from 'react';
import { RouteComponentProps } from 'react-router';
import Link, { LinkedComponent } from 'valuelink';
interface CarPartModel {
  ID: number;
  PartNumber: number;
  PartName: string;
  Description: string;
  CarManufacturer: string;
}
const carManufacturers = [
  { label: "Ford", value: 1 },
  { label: "Chevrolett", value: 2 },
  { label: "Tesla", value: 3 },
  { label: "Chrysler", value: 4 },
  { label: "Honda", value: 5 },
  { label: "Toyota", value: 6 },
];
export class CarPart extends React.Component<RouteComponentProps<{}>, CarPartModel> {
  state: CarPartModel = {
      ID: 0,
      PartNumber: 0,
      PartName: '',
      Description: '',
      CarManufacturer: ''
  };
  constructor() {
      super();
      this.state = {
          ID: 0,
          PartNumber: 0,
          PartName: '',
          Description: '',
          CarManufacturer: ''
      };
      this.handleSave = this.handleSave.bind(this);
      this.handleDelete = this.handleDelete.bind(this);
  }
  handleSave = () => {
      fetch('api/CarParts/SavePartData', {
          method: 'post',
          headers: new Headers({
              "Content-Type": "application/json",
              Accept: "application/json"
          }),
          body: JSON.stringify(this.state)
      }).then(function (response) {
          if (response.status !== 200) {
              console.log('fetch returned not ok' + response.status);
          }
      }).catch(function (err) {
          console.log(`error: ${err}`);
          })
  }
  handleDelete = () => {
      if (!confirm("Do you want to delete employee with Id: " + this.state.ID))
          return;
      else {
          fetch('api/CarParts/Delete/' + this.state.ID, {
              method: 'delete'
          }).then(data => {
              this.state =
                  {
                      ID: 0,
                      PartNumber: 0,
                      PartName: '',
                      Description: '',
                      CarManufacturer: ''
                  };
          });
      } 
  }
  public handleIdChange(event: any): void {
      this.state.ID = event.target.value;
  }
  public handlePartNumberChange(event: any): void {
      this.state.PartNumber = event.target.value;
  }
  public handlePartNameChange(event: any): void {
      this.state.PartName = event.target.value;
  }
  public handleDescriptionChange(event: any): void {
      this.state.Description = event.target.value;
  }
  public handleManufacturerChange(event: any): void {
      this.state.CarManufacturer = event.target.value;
  }
  public render() {
      return <div>
          <h1>Car Parts</h1>
          <div className='row'>
              <div className='col-md-2'>
                  <label>Part Id: </label>
              </div>
              <div className='col-md-2'>
                  <input className="form-control" type="text" name="partId" onChange={e => this.handleIdChange(e)} required />
              </div>
              <div className='col-md-8'>
              </div>
          </div>
          <div className='row'>
              <div className='col-md-2'>
                  <label>Part Number: </label>
              </div>
              <div className='col-md-2'>
                  <input className="form-control" type="text " name="partNumber" onChange={e => this.handlePartNumberChange(e)} required />
              </div>
              <div className='col-md-8'>
              </div>
          </div>
          <div className='row'>
              <div className='col-md-2'>
                  <label>Part Name: </label>
              </div>
              <div className='col-md-2'>
                  <input className="form-control" type="text" name="partName" onChange={e => this.handlePartNameChange(e)} required />
              </div>
              <div className='col-md-8'>
              </div>               
          </div>
          <div className='row'>
              <div className='col-md-2'>
                  <label>Description: </label>
              </div>
              <div className='col-md-2'>
                  <input className="form-control" type="text" name="description" onChange={e => this.handleDescriptionChange(e)} required />
              </div>
              <div className='col-md-8'>
              </div>
          </div>
          <div className='row'>
              <div className='col-md-2'>
                  <label>Car Manufacturer:</label>
              </div>
              <div className='col-md-2'>
                  <select onChange={e => this.handleManufacturerChange(e)}>
                      <option value="volvo">Volvo</option>
                      <option value="saab">Saab</option>
                      <option value="mercedes">Mercedes</option>
                      <option value="chrysler">Chrysler</option><option value="saab">Saab</option>
                      <option value="dodge">Dodge</option>
                      <option value="ford">Ford</option>
                  </select>
              </div>
              <div className='col-md-8'>
              </div>               
          </div>
          <div className='row mt-3'> </div>
          <div className='row'>
              <div className='col-md-1'>
                  <button onClick={this.handleSave} className='btn btn-info btn-lg'><span className="glyphicon glyphicon-ok"></span>
                      &nbsp;&nbsp;Save
                  </button>
              </div>
              <div className='col-md-1'>
                  <button onClick={this.handleDelete} className='btn btn-info btn-lg'><span className="glyphicon glyphicon-remove"></span>
                      &nbsp;&nbsp;Delete
                  </button>
              </div>
              <div className='col-md-9'>
              </div>
          </div>
          </div>
          ;
  }
}

我添加的最后一项是项目服务。为此,我添加了一个services文件夹,并添加了一个名为CarPartService.cs的类和ICarPartService.cs接口。服务类具有c#中的实际代码,该代码将与数据访问层(DAL)交互以执行CRUD操作。我没有在演示中包含它,因为它超出了项目目的范围,项目目的是显示使用React代码的能力。但是出于测试目的,在服务方法中添加断点并在调试中运行应用程序。

ICarPartInterface.cs的内容如下:

using ReactSample.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace ReactSample.Services
{
   public interface ICarPartService
   {
       CarPartViewModel GetCartPart(int carPartId);
       bool SaveCartPart(CarPartViewModel carPart);
       bool UpdateCarPart(CarPartViewModel carPart);
       bool Delete(int carPartId);
   }
}

CarPartService.cs的代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using ReactSample.ViewModels;
namespace ReactSample.Services
{
   public class CarPartsService : ICarPartService
   {
       public bool Delete(int carPartId)
       {
           try
           {
               // Find the car part associated with the given Id and delete it
               return true;
           }
           catch(Exception ex)
           {
               // Log error message in case of error
           }
           return false;
       }
       public CarPartViewModel GetCartPart(int carPartId)
       {
           var carPart = new CarPartViewModel();
           try
           {
               // Find the car part associated with the given Id, polulate carPart object and return it
               return carPart;
           }
           catch (Exception ex)
           {
               // Log error message in case of error
           }
           return null;
       }
       /// <summary>
       /// Receives car part object and query database
       /// if record exists then updates
       /// if record does not exist then inserts
       /// </summary>
       /// <param name="carPart"></param>
       /// <returns></returns>
       public bool SaveCartPart(CarPartViewModel carPart)
       {
           try
           {
               // Save the car part object into database
               return true;
           }
           catch (Exception ex)
           {
               // Log error message in case of error
           }
           return false;
       }
       public bool UpdateCarPart(CarPartViewModel carPart)
       {
           try
           {
               // Find the car part associated with the given Id and update fields using parameter object
               return true;
           }
           catch (Exception ex)
           {
               // Log error message in case of error
           }
           return false;
       }
   }
}

为了使用服务层,我决定将它注入控制器。所以我在Controllers文件夹中创建了一个CarPartsController并添加了以下代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using ReactSample.Services;
using ReactSample.ViewModels;
namespace ReactSample.Controllers
{
   [Produces("application/json")]
   [Route("api/[controller]")]
   public class CarPartsController : Controller
   {
       ICarPartService _carPartService;
       private readonly string[] CarManufacaturers = new[]
       {
           "Chryssler", "Dodge", "Ford", "Jeep", "Chevrolett", "Honda", "Toyota", "Subaru", "Nisan", "Kia"
       };
       public CarPartsController(
           ICarPartService carPartService
       )
       {
           _carPartService = carPartService;
       }
       [HttpGet("{id}", Name = "Get")]
       public CarPartViewModel Get(int id)
       {
           return _carPartService.GetCartPart(id);
       }
       [HttpPost("SavePartData")]
       public void SavePartData([FromBody]CarPartViewModel carPart)
       {
           _carPartService.SaveCartPart(carPart);
       }
       // PUT: api/Sample/5
       [HttpPut("{id}")]
       public void Update(int id, [FromBody]CarPartViewModel carPart)
       {
           _carPartService.UpdateCarPart(carPart);
       }
       // DELETE: api/ApiWithActions/5
       [HttpDelete("Delete/{id}")]
       public void Delete(int id)
       {
           _carPartService.Delete(id);
       }
   }
}

你可以注意到在演示中我在这个控制器中使用了两个方法,SavePartDataDelete。我把了其他方法保留,以防我决定为这个项目添加更多功能......只是为了好玩。如果您注意到此控制器构造函数具有分配给_carPartService变量的carPartService参数。为了完成这项工作,我们需要将以下行添加到Starup.cs文件中,ConfigureServices方法最后将看起来像这样的:

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
    services.AddScoped<ICarPartService, CarPartsService>();
    services.AddMvc();
}

添加bootstrap并运行解决方案后,我们得到:

https://img-blog.csdnimg.cn/20181221211022642

https://img-blog.csdnimg.cn/20181221211022662

快乐的编码!

 

原文地址:https://www.codeproject.com/Articles/1271257/React-in-one-day

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值