一、理解和安装 AngularJs

1、AngularJS简介

AngularJS是由Google的一个团队开发的JavaScript框架。

该团队创建了一个可扩展、可测试的框架,而且功能非常强大,直接数据绑定、服务器间通信、视图管理、历史管理、定位、验证等。

Angular都是关于JavaScript和HTML


2、本章目标

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>

第12章 应用 AngularJS 构建单页面应用程序(MVC+EntityFramework +Web API+AngularJs)的更多相关文章

  1. HTML5 播放 RTSP 视频的实例代码

    目前大多数网络摄像头都是通过 RTSP 协议传输视频流的,但是 HTML 并不标准支持 RTSP 流。本文重点给大家介绍HTML5 播放 RTSP 视频的实例代码,需要的朋友参考下吧

  2. 利用Node实现HTML5离线存储的方法

    这篇文章主要介绍了利用Node实现HTML5离线存储的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  3. 详解如何通过H5(浏览器/WebView/其他)唤起本地app

    这篇文章主要介绍了详解如何通过H5(浏览器/WebView/其他)唤起本地app的相关资料,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  4. H5混合开发app如何升级的方法

    本篇文章主要介绍了H5混合开发app如何升级的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  5. AmazeUI 折叠面板的实现代码

    这篇文章主要介绍了AmazeUI 折叠面板的实例代码,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  6. HTML5手指下滑弹出负一屏阻止移动端浏览器内置下拉刷新功能的实现代码

    这篇文章主要介绍了HTML5手指下滑弹出负一屏阻止移动端浏览器内置下拉刷新功能的实现代码,代码简单易懂,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧

  7. Html5 video标签视频的最佳实践

    这篇文章主要介绍了Html5 video标签视频的最佳实践,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  8. html5唤起app的方法

    这篇文章主要介绍了html5唤起app的方法的相关资料,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  9. HTML5拍照和摄像机功能实战详解

    这篇文章主要介绍了HTML5拍照和摄像机功能实战详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  10. ios – 在没有iPhone6s或更新的情况下测试ARKit

    我在决定下载Xcode9之前.我想玩新的框架–ARKit.我知道要用ARKit运行app我需要一个带有A9芯片或更新版本的设备.不幸的是我有一个较旧的.我的问题是已经下载了新Xcode的人.在我的情况下有可能运行ARKit应用程序吗?那个或其他任何模拟器?任何想法或我将不得不购买新设备?解决方法任何iOS11设备都可以使用ARKit,但是具有高质量AR体验的全球跟踪功能需要使用A9或更高版本处理器的设备.使用iOS11测试版更新您的设备是必要的.

随机推荐

  1. Angular2 innerHtml删除样式

    我正在使用innerHtml并在我的cms中设置html,响应似乎没问题,如果我这样打印:{{poi.content}}它给了我正确的内容:``但是当我使用[innerHtml]=“poi.content”时,它会给我这个html:当我使用[innerHtml]时,有谁知道为什么它会剥离我的样式Angular2清理动态添加的HTML,样式,……

  2. 为Angular根组件/模块指定@Input()参数

    我有3个根组件,由根AppModule引导.你如何为其中一个组件指定@input()参数?也不由AppModalComponent获取:它是未定义的.据我所知,你不能将@input()传递给bootstraped组件.但您可以使用其他方法来做到这一点–将值作为属性传递.index.html:app.component.ts:

  3. angular-ui-bootstrap – 如何为angular ui-bootstrap tabs指令指定href参数

    我正在使用角度ui-bootstrap库,但我不知道如何为每个选项卡指定自定义href.在角度ui-bootstrap文档中,指定了一个可选参数select(),但我不知道如何使用它来自定义每个选项卡的链接另一种重新定义问题的方法是如何使用带有角度ui-bootstrap选项卡的路由我希望现在还不算太晚,但我今天遇到了同样的问题.你可以通过以下方式实现:1)在控制器中定义选项卡href:2)声明一个函数来改变控制器中的散列:3)使用以下标记:我不确定这是否是最好的方法,我很乐意听取别人的意见.

  4. 离子框架 – 标签内部的ng-click不起作用

    >为什么标签标签内的按钮不起作用?>但是标签外的按钮(登陆)工作正常,为什么?>请帮我解决这个问题.我需要在点击时做出回复按钮workingdemo解决方案就是不要为物品使用标签.而只是使用divHTML

  5. Angular 2:将值传递给路由数据解析

    我正在尝试编写一个DataResolver服务,允许Angular2路由器在初始化组件之前预加载数据.解析器需要调用不同的API端点来获取适合于正在加载的路由的数据.我正在构建一个通用解析器,而不是为我的许多组件中的每个组件设置一个解析器.因此,我想在路由定义中传递指向正确端点的自定义输入.例如,考虑以下路线:app.routes.ts在第一个实例中,解析器需要调用/path/to/resourc

  6. angularjs – 解释ngModel管道,解析器,格式化程序,viewChangeListeners和$watchers的顺序

    换句话说:如果在模型更新之前触发了“ng-change”,我可以理解,但是我很难理解在更新模型之后以及在完成填充更改之前触发函数绑定属性.如果您读到这里:祝贺并感谢您的耐心等待!

  7. 角度5模板形式检测形式有效性状态的变化

    为了拥有一个可以监听其包含的表单的有效性状态的变化的组件并执行某些组件的方法,是reactiveforms的方法吗?

  8. Angular 2 CSV文件下载

    我在springboot应用程序中有我的后端,从那里我返回一个.csv文件WheniamhittingtheURLinbrowsercsvfileisgettingdownloaded.现在我试图从我的角度2应用程序中点击此URL,代码是这样的:零件:服务:我正在下载文件,但它像ActuallyitshouldbeBook.csv请指导我缺少的东西.有一种解决方法,但您需要创建一个页面上的元

  9. angularjs – Angular UI-Grid:过滤后如何获取总项数

    提前致谢:)你应该避免使用jQuery并与API进行交互.首先需要在网格创建事件中保存对API的引用.您应该已经知道总行数.您可以使用以下命令获取可见/已过滤行数:要么您可以使用以下命令获取所选行的数量:

  10. angularjs – 迁移gulp进程以包含typescript

    或者我应该使用tsc作为我的主要构建工具,让它解决依赖关系,创建映射文件并制作捆绑包?

返回
顶部