一、理解和安装 AngularJs
1、AngularJS简介AngularJS是由Google的一个团队开发的JavaScript框架。
该团队创建了一个可扩展、可测试的框架,而且功能非常强大,直接数据绑定、服务器间通信、视图管理、历史管理、定位、验证等。
Angular都是关于JavaScript和HTML
3、入门
4、向网站中添加AngularJS
在NuGet包管理控制台执行Install-Package AngularJS.core 或 解决方案NuGet程序包搜索 “AngularJS” 安装。
@section scripts{ <script src="~/Scripts/angular.js"></script> } @* <div ng-app> {{2+3}} </div> *@ @*HTML5规范要求所有的用户自定义属性以"data-"开头,所以data-ng-app是符合HTML5规范的写法。*@ <div ng-app> {{true?"true":"false"}} </div>
输出结果:5
输出结果:true
注意:注释一个,另一个才能显示true
@* Angular核心指令都是一个“ng”前缀 ng-app告知Angular跳入并初始化应用程序,并寻找其他内部指令和模板来控制DOM节,这一过程通常被称作编译DOM。 {{}} 双花括号是HTML模板 *@
5、数据库设置
在NuGet包管理控制台执行Install-Package EntityFramework 或 解决方案NuGet程序包搜索 “EntityFramework” 安装。
Model文件夹下创建Movie.cs
/// <summary> /// 存储数据库中的数据 /// </summary> public class Movie { public int Id { get; set; } public string Title { get; set; } public int ReleaseYear { get; set; } public int Runtime { get; set; } }Model文件夹下创建MovieDb.cs
/// <summary> /// 添加一个DbSet类型的属性来实现对电影对象的添加、删除和查询 /// </summary> public class MovieDb:DbContext { public DbSet<Movie> Movies { get; set; } }控制台执行 Enable-Migrations(数据库上使用迁移)
迁移会在项目中创建Migrations文件,并创建Configuration.cs文件,会拥有一个Seed方法类。添加方法。
internal sealed class Configuration : DbMigrationsConfiguration<WebApplication2.Models.MovieDb> { public Configuration() { //程序包管理控制台执行 Enable-Migrations 迁移 //启动自动迁移 AutomaticMigrationsEnabled = true; } protected override void Seed(WebApplication2.Models.MovieDb context) { 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 } ); } }
命令执行 update-database命令创建数据库。
二、创建Web API
1、Controllers中添加MovieController
2、运行应用程序,浏览器导航到/api/movie。可以看到电影信息编码成XML或JSon
三、创建应用程序和模块
1、Views/Home/Index.cshtml
@section scripts{ <script src="~/Scripts/angular.js"></script> <script src="~/Scripts/angular-route.js"></script>@*angular路由*@ <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> } @*指示Angular把atTheMovies作为应用程序模块加载*@ <div data-ng-app="atTheMovies"> @*ng-view指令是一个占位符,Angular用它来插入当前视图*@ <ng-view></ng-view> </div>
2、结构:
3、JS脚本
atTheMovies.js
angular路由需要在Index.cshtml 添加引用angular-route.js
//变量angular是全局Angular对象。 //和jQuery API通过全局变量$获取一样,Angular通过变量angular来访问顶级API. //模块函数创建了一个新模块 atTheMovies,然而第2个参数即空数组 (function () { //angular路由: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" }); }; //使用应用程序模块的config方法描述想让Angular处理的路由。 //通过ngRoute模块提供的$routeProvider组件实现路由描述。 app.config(config); //使用constant方法注册常量值(第1个参数作key,第2个参数作为与key关联的值)。 //任何需要调用MovieController的组件现在可以请求movieApiUrl依赖,但只有movieService需要它。 app.constant("movieApiUrl","/api/movie/"); }());movieService.js
//自定义$http服务 //服务是通过提供检索电影列表的方法模拟MovieController的服务器API //通过ID获取、更新、创建和删除电影信息。 (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")))
ListController.js
//引用了前面脚本中创建的atTheMovies模块。 //这样在函数中就可以通过变量app来访问atTheMovies模块 (function (app) { //定义了ListController函数,首字母大写 //$scope变量是Angular构建的对象,它作为参数传递给了控制器函数。 //控制器负责初始化$scope中的数据和行为,因为$scope最后是有视图使用模型对象。 //通过向$scope对象添加message特性,视图就可以通过引用消息的模块使用控制器构建模型。 //var ListController = function ($scope) { // $scope.message = "Hello,World!"; //}; //当控制器或其他组件需要使用服务时,会向Angular请求服务引用,并把服务作为参数传递给控制器或组件的注册函数,比如ListController函数。 //参数:$http 与服务器上的WebAPI端点进行通信。 //当$http服务作为参数传递给控制器之后,通过HTTP GET调用Web API终端,控制器就可以使用$http服务从服务器检索电影。 var ListController = function($scope,movieService) { movieService.getall() .success(function (data) { $scope.movies = data; }); //$scope的delete方法,delete方法可以通过ng-click指令调用。 //从理论上讲,delete方法首先使用movieService调用服务器,然后删除电影。 //只有当调用服务器成功后,delete方法才去调用removeMovieById函数来删除电影 $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.movie.splice(i,1); break; } } }; $scope.create = function () { $scope.edit = { movie: { title: "",runtime: 0,releaseYear: 0 } }; }; }; //使用组件需要的依赖的名称来注解组件 //ListController.$inject = ["$scope","$http"]; //Angular调用控制器方法来进行控制器构造函数注册 //控制器方法的第1个参数的控制器名称,Angular使用这个名称来查找控制器。 //第2个参数是与这个名称关联的构造函数。 app.controller("ListController",ListController) }(angular.module("atTheMovies"))); //方法二:获取atTheMovies的引用 //(function (app) { // var app = angular.module("atTheMovies"); //}());DetailsController.js
(function (app) { var DetailsController = function ($scope,$routeParams,movieService) { var id=$routeParams.id; movieService.getById(id) .then(function (result) { $scope.movie = result.data; }); $scope.edit = function () { $scope.edit.movie = angular.copy($scope.movie); }; }; app.controller("DetailsController",DetailsController) }(angular.module("atTheMovies")));EditController.js
(function (app) { var EditController = function ($scope,movieService) { 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; }); }; $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(); } }; }; EditController.$inject = ["$scope","movieService"]; app.controller("EditController",EditController); }(angular.module("AtTheMovies")));
4、Html
list.html
<!-- ng-controller指令把ListController(js文件名)添加到应用程序的一个div中 Angular 通过控制器名称来查找控制器,创建控制器。 通过添加Angular模板到标记语言,就可以看到控制器、视图、模型 --> <div ng-controller="ListController"> <!-- {{message}} {{movies.length}} --> <table> <!--ng-repeat指令和js中for循环类似.--> <tr ng-repeat="movie in movies"> <td>{{movie.Title}}</td> <td> <a href="#/details/{{movie.Id}}">详细</a> <button class="btn btn-default" ng-click="delete(movie)"> 删除 </button></td> </tr> </table> <button class="btn" ng-click="create()">Create</button> <div class="span6"> <div> <!-- ng-include 指令包含编辑视图 --> <div ng-include="'/Client/views/edit.html'"></div> </div> </div> </div>edit.html
<div ng-controller="EditController"> <!-- ng-show指令基于提供的表达式隐藏或展示DOM节 只有当模型isEditable函数返回true时,表单元素才会展示 --> <fieldset ng-show="isEditable()"> <label for="title"> Title </label> <!--ng-model指令在模型和表单元素之间设置双向数据绑定--> <input id="title" type="text" ng-model="edit.movie.title" required /> <label for="release"> Release Year </label> <input id="release" type="number" ng-model="edit.movie.releaseYear" required min="1900" max="2030" /> <label for="runtime"> Length </label> <input id="runtime" type="number" ng-model="edit.movie.runtime" required min="0" max="500" /> <button ng-click="save()">Save</button> <button ng-click="cancel()">Cancel</button> </fieldset> </div>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 class="span6"> <div> <div ng-include="'/Client/views/edit.html'"></div> </div> </div> </div>