【MVC5】First AngularJS

来源:互联网 时间:1970-01-01

※本文参照《ASP.NET MVC 5高级编程(第5版)》

1.创建Web工程

1-1.选择ASP.NET Web Application→Web API

工程名为【atTheMovie】

1-2.添加AngularJS

在Package Manager Console执行如下命令:

Install-Package AngularJS.core

1-3.添加EntityFramework

在Package Manager Console执行如下命令:

Install-Package EntityFramework

1-4.添加AngularJS.Route

Install-Package -IncludePrerelease AngularJS.Route

2.添加Model

2-1.在Models目录中添加Movie类

using System.Data.Entity;namespace atTheMovies.Models{ public class Movie { public int Id { get; set; } public string Title { get; set; } public int ReleaseYear { get; set; } public int RunTime { get; set; } } public class MovieDb : DbContext { public DbSet<Movie> Movies { get; set; } }}

2-2.根据Model更新DB,生成Table

在Package Manager Console执行如下命令,会在Migrations目录中追加一个Configuration.cs的类:

Enable-Migrations -ContextTypeName atTheMovies.Models.MovieDb

修改Configuration.cs类的Seed方法如下:

namespace atTheMovies.Migrations{ using Models; using System; using System.Data.Entity; using System.Data.Entity.Migrations; using System.Linq; internal sealed class Configuration : DbMigrationsConfiguration<atTheMovies.Models.MovieDb> { public Configuration() { AutomaticMigrationsEnabled = true; } protected override void Seed(atTheMovies.Models.MovieDb context) { // This method will be called after migrating to the latest version. // You can use the DbSet<T>.AddOrUpdate() helper extension method // to avoid creating duplicate seed data. E.g. // // context.People.AddOrUpdate( // p => p.FullName, // new Person { FullName = "Andrew Peters" }, // new Person { FullName = "Brice Lambson" }, // new Person { FullName = "Rowan Miller" } // ); // context.Movies.AddOrUpdate(m => m.Title, new Movie { Title = "Star Wars", ReleaseYear = 1977, RunTime = 121 }, new Movie { Title = "Inception", ReleaseYear = 2010, RunTime = 148 }, new Movie { Title = "Toy Story", ReleaseYear = 1995, RunTime = 81 } ); } }}

在Package Manager Console执行如下命令,执行上面的代码:

update-database

3.使用基架根据Model生成Controller

右击Controller目录,点击追加Controller;选择【Web API 2 Controller with actions, using Entiry Framework】;

Model选择刚刚追加的Movie;
Data context class选择Movie类中的DBContext(MovieDb);
Controller name设置为MovieController;

自动生成的MovieController的代码如下:

using System;using System.Collections.Generic;using System.Data;using System.Data.Entity;using System.Data.Entity.Infrastructure;using System.Linq;using System.Net;using System.Net.Http;using System.Web.Http;using System.Web.Http.Description;using atTheMovies.Models;namespace atTheMovies.Controllers{ public class MovieController : ApiController { private MovieDb db = new MovieDb(); // GET: api/Movie public IQueryable<Movie> GetMovies() { return db.Movies; } // GET: api/Movie/5 [ResponseType(typeof(Movie))] public IHttpActionResult GetMovie(int id) { Movie movie = db.Movies.Find(id); if (movie == null) { return NotFound(); } return Ok(movie); } // PUT: api/Movie/5 [ResponseType(typeof(void))] public IHttpActionResult PutMovie(int id, Movie movie) { if (!ModelState.IsValid) { return BadRequest(ModelState); } if (id != movie.Id) { return BadRequest(); } db.Entry(movie).State = EntityState.Modified; try { db.SaveChanges(); } catch (DbUpdateConcurrencyException) { if (!MovieExists(id)) { return NotFound(); } else { throw; } } return StatusCode(HttpStatusCode.NoContent); } // POST: api/Movie [ResponseType(typeof(Movie))] public IHttpActionResult PostMovie(Movie movie) { if (!ModelState.IsValid) { return BadRequest(ModelState); } db.Movies.Add(movie); db.SaveChanges(); return CreatedAtRoute("DefaultApi", new { id = movie.Id }, movie); } // DELETE: api/Movie/5 [ResponseType(typeof(Movie))] public IHttpActionResult DeleteMovie(int id) { Movie movie = db.Movies.Find(id); if (movie == null) { return NotFound(); } db.Movies.Remove(movie); db.SaveChanges(); return Ok(movie); } protected override void Dispose(bool disposing) { if (disposing) { db.Dispose(); } base.Dispose(disposing); } private bool MovieExists(int id) { return db.Movies.Count(e => e.Id == id) > 0; } }}

4.修改既存的Index.cshtml代码

这里已经把所有相关的JS追加好了,具体代码见后面部分。

@section scripts { <script src="~/Scripts/angular.js"></script> <script src="~/Scripts/angular-route.js"></script> <script src="~/Client/Scripts/atTheMovies.js"></script> <script src="~/Client/Scripts/ListController.js"></script> <script src="~/Client/Scripts/DetailsController.js"></script> <script src="~/Client/Scripts/movieService.js"></script> <script src="~/Client/Scripts/EditController.js"></script>}<div ng-app="atTheMovies"> <ng-view></ng-view></div>

5.注册模块、路由、常量等

5-1.创建Client/Scripts目录;追加atTheMovies.js;

(function () { // 创建了一个新模块atTheMovies // 第二个参数为空[],代表这个模块依赖于核心Angular模块ng // var app = angular.module("atTheMovies", []); // 添加依赖模块 ngRoute 路由 var app = angular.module("atTheMovies", ["ngRoute"]); var config = function ($routeProvider) { $routeProvider .when("/list", { templateUrl: "/client/views/list.html" }) .when("/details/:id", { templateUrl: "/client/views/details.html" }) .otherwise({ redirectTo: "/list" }); }; app.config(config); // 注册常量值 app.constant("movieApiUrl", "/api/movie/");}());

6.创建Service

6-1.在Client/Scripts目录中追加movieService.js;

(function (app) { var movieService = function ($http, movieApiUrl) { var getAll = function () { return $http.get(movieApiUrl); }; var getById = function (id) { return $http.get(movieApiUrl + id); }; var update = function (movie) { return $http.put(movieApiUrl + movie.Id, movie); }; var create = function (movie) { return $http.post(movieApiUrl, movie); }; var destroy = function (movie) { return $http.delete(movieApiUrl + movie.Id); }; return { getAll: getAll, getById: getById, update: update, create: create, delete: destroy, }; }; app.factory("movieService", movieService);})(angular.module("atTheMovies"));

7.创建ListController和ListView

7-1.在Client/Scripts目录中追加ListController.js;

(function (app) { //var ListController = function ($scope, $http) { // $scope.message = "Hello, World!"; // $http.get("/api/movie").success(function (data) { // $scope.movies = data; // }); //}; //ListController.$inject = ["$scope", "$http"]; // 使用movieService var ListController = function ($scope, movieService) { movieService .getAll() .success(function (data) { $scope.movies = data; }); $scope.create = function () { $scope.edit = { movie: { Title: "", RunTime: 0, ReleaseYear: new Date().getFullYear() } }; }; $scope.delete = function (movie) { movieService.delete(movie) .success(function () { removeMovieById(movie.Id); }); }; var removeMovieById = function (id) { for (var i = 0; i < $scope.movies.length; i++) { if ($scope.movies[i].Id == id) { $scope.movies.splice(i, 1); break; } } }; }; // 注册新控制器 // 参数: // 控制器名称 // 与这个名称关联的构造函数 app.controller("ListController", ListController);})(angular.module("atTheMovies"));// 使用临时的调用函数表达式来代替创建全局变量// 还有一种方法可以获取atTheMovies的引用// (function (app) {// var app = angular.module("atTheMovies");// }());.

7-2.在Client/Views目录中追加list.html;

<div ng-controller="ListController"> <table class="table" > <tr ng-repeat="movie in movies"> <td>{{movie.Title}}</td> <td> <a class="btn btn-default" href="#/details/{{movie.Id}}">Details</a> <button class="btn btn-default" ng-click="delete(movie)">Delete</button> </td> </tr> </table> <button class="btn btn-default" ng-click="create()">Create</button> <div ng-include="'/Client/views/edit.html'"></div></div>

8.创建DetailsController和DetailsView

8-1.在Client/Scripts目录中追加DetailsController.js;

(function (app) { //var DetailsController = function ($scope, $http, $routeParams) { // var id = $routeParams.id; // $http.get("/api/movie/" + id) // .success(function (data) { // $scope.movie = data; // }); //}; // 使用movieService var DetailsController = function ($scope, $routeParams, movieService) { var id = $routeParams.id; movieService .getById(id) .success(function (data) { $scope.movie = data; }); $scope.edit = function () { $scope.edit.movie = angular.copy($scope.movie); }; }; app.controller("DetailsController", DetailsController);})(angular.module("atTheMovies"));

8-2.在Client/Views目录中追加details.html;

<div ng-controller="DetailsController"> <h2>{{movie.Title}}</h2> <div> Released in {{movie.ReleaseYear}}. </div> <div> {{movie.RunTime}} minutes long. </div> <button ng-click="edit()">Edit</button> <div ng-include="'/Client/views/edit.html'"></div></div>

9.创建EditController和EditView

9-1.在Client/Scripts目录中追加EditController.js;

(function (app) { var EditController = function ($scope, movieService) { $scope.isEditable = function () { return $scope.edit && $scope.edit.movie; }; $scope.cancel = function () { $scope.edit.movie = null; }; $scope.save = function () { if ($scope.edit.movie.Id) { updateMovie(); } else { createMovie(); } }; var updateMovie = function () { movieService.update($scope.edit.movie) .success(function () { angular.extend($scope.movie, $scope.edit.movie); $scope.edit.movie = null; }); }; var createMovie = function () { movieService.create($scope.edit.movie) .success(function (movie) { $scope.movies.push(movie); $scope.edit.movie = null; }); }; }; app.controller("EditController", EditController);})(angular.module("atTheMovies"));

9-2.在Client/Views目录中追加edit.html;

<div ng-controller="EditController"> <form ng-show="isEditable()"> <fieldset> <div class="form-group"> <label for="title"> Title </label> <input id="title" type="text" ng-model="edit.movie.Title" required class="form-control" /> </div> <div class="form-group"> <label for="release"> Release Year </label> <input id="release" type="number" ng-model="edit.movie.ReleaseYear" required min="1900" max="2030" class="form-control" /> </div> <div class="form-group"> <label for="runtime"> Length </label> <input id="runtime" type="number" ng-model="edit.movie.RunTime" required min="0" max="500" class="form-control" /> </div> <button class="btn btn-default" ng-click="save()">Save</button> <button class="btn btn-default" ng-click="cancel()">Cancel</button> </fieldset> </form></div>

10.运行效果

点击Create按钮

点击Delete按钮

点击Details按钮

点击Edit按钮

11.注意点

11-1.JS模型中属性名的大小写

一定要保持和CS代码中模型属性名大小写一致;否则会导致画面上显示不出来值或者画面上的值没有更新到DB中。



相关阅读:
Top