[译]用AngularJS构建大型ASP.NET单页应用(二)

原文地址:http://www.codeproject.com/Articles/808213/Developing-a-Large-Scale-Application-with-a-Single

客户管理页面-新增、修改客户

  单页应用中的页面与asp.net页面类似,两者都是html页面。 对于asp.net,浏览器加载html、js、数据,然后,浏览器进展示。而单页应用,页面内容通过ng-view 指令被注入到一个div标签中。

  页面初始化时,浏览器通常只渲染html代码。 若在单页应用中使用RequireJS,js会被动态加载。 当页面加载完,浏览器以ajax异步调用的方式从服务器读取数据。

  使用SPA的好处之一:性能。SPA的每一个页面会被缓存到客户端,最终你所有的页面都会被缓存,而你只是通过AJAX请求通过网络获取服务器数据而已. 所有这些都促成了高效的响应时间,以增强的用户体验.

<!-- CustomerMaintenance.html -->

<div ng-controller="customerMaintenanceController" ng-init="initializeController()">

<h3> Customer Maintenance  </h3>
     <table class="table" style="width:100%">
<tr>
<td class="input-label" align="right"> <label class="required">Customer Code: </label> </td>
<td class="input-box">
<div ng-bind="CustomerCode" ng-show="DisplayMode"> </div>
<div ng-show="EditMode">
     <input ng-model="CustomerCode" type="text" style="width: 300px"
     ng-class="{‘validation-error‘: CustomerCodeInputError}" />
</div>
</td>
</tr>
<tr>
<td class="input-label" align="right"> <label class="required">Company Name: </label> </td>
<td class="input-box">
<div ng-bind="CompanyName" ng-show="DisplayMode"> </div>
<div ng-show="EditMode">
     <input ng-model="CompanyName" type="text" style="width: 300px"
            ng-class="{‘validation-error‘: CompanyNameInputError}" />
</div>
</td>
</tr>
<tr>
<td class="input-label" align="right"> <label>Address: </label> </td>
<td class="input-box">
<div ng-bind="Address" ng-show="DisplayMode"> </div>
<div ng-show="EditMode">
     <input ng-model="Address" type="text" style="width: 300px" />
</div>
</td>
</tr>
<tr>
<td class="input-label" align="right"> <label>City: </label> </td>
<td class="input-box">
<div ng-bind="City" ng-show="DisplayMode"> </div>
<div ng-show="EditMode">
     <input ng-model="City" type="text" style="width: 300px" />
</div>
</td>
</tr>
<tr>
<td class="input-label" align="right"> <label>Region: </label> </td>
<td class="input-box">
<div ng-bind="Region" ng-show="DisplayMode"> </div>
<div ng-show="EditMode">
     <input ng-model="Region" type="text" style="width: 300px" />
</div>
</td>
</tr>
<tr>
<td class="input-label" align="right"> <label>Postal Code: </label> </td>
<td class="input-box">
<div ng-bind="PostalCode" ng-show="DisplayMode"> </div>
<div ng-show="EditMode">
     <input ng-model="PostalCode" type="text" style="width: 300px" />
</div>
</td>
</tr>
<tr>
<td class="input-label" align="right"> <label>Country: </label> </td>
<td class="input-box">
<div ng-bind="CountryCode" ng-show="DisplayMode"> </div>
<div ng-show="EditMode">
     <input ng-model="CountryCode" type="text" style="width: 300px" />
</div>
</td>
</tr>
<tr>
<td class="input-label" align="right"> <label>Phone Number: </label> </td>
<td class="input-box">
<div ng-bind="PhoneNumber" ng-show="DisplayMode"> </div>
<div ng-show="EditMode">
     <input ng-model="PhoneNumber" type="text" style="width: 300px" />
</div>
</td>
</tr>
<tr>
<td class="input-label-bottom" align="right"> <label>Web Site URL: </label> </td>
<td class="input-box-bottom">
<div ng-bind="WebSiteURL" ng-show="DisplayMode"> </div>
<div ng-show="EditMode">
     <input ng-model="WebSiteURL" type="text" style="width: 300px" />
</div>
</td>
</tr>
</table>

<span ng-show="ShowCreateButton">
<button class="btn btn-primary btn-large" ng-click="createCustomer()">Create </button> </span>
<span ng-show="ShowEditButton">
<button class="btn btn-primary btn-large" ng-click="editCustomer()">Edit </button> </span>
<span ng-show="ShowUpdateButton">
<button class="btn btn-primary btn-large" ng-click="updateCustomer()">Update </button> </span>
<span ng-show="ShowCancelButton">
<button class="btn btn-primary btn-large" ng-click="cancelChanges()">Cancel </button> </span>
<div style="padding-top:20px">

<alert ng-repeat="alert in alerts" type="{{alert.type}}" close="closeAlert($index)">
<div ng-bind-html="MessageBox"> </div> </alert>

</div>
</div>

数据绑定及Separation of Concerns (SoC)

查看上面用于示例程序的顾客维护页面的HTML内容,你能够看到这是一个看起来很清晰,很容易阅读的HTML。内容里面也没有引用任何JavaScript。

借助于data-binding指令,AngularJS提供了内容视图及内容控制器之间清晰的关注点分离. 对于输入控制,双向数据绑定通过ng-bind这个指令以及客户管理控制器的$scope属性得到了实现. AngularJS中的数据绑定功能同其它的JavaScript库,如KnockoutJS,功能相似, 对于文档对象模型的转换需求已经成为过去式。

ng-show 指令是的显示隐藏的HTML内容变得容易. 对于客户管理页面来说,这将会让页面只用设置一个JavaScript的AngularJS $scope变量,就可以同时支持编辑模式和只读模式. ng-click  指令将会执行在按下按钮时执行的控制器函数.

客户管理控制器

示例中的每一个控制器都会被封装到一个RequireJS定义语句中,帮助AngularJS对控制器进行注册. 此外,定义语句将告知RequireJS顾客维护控制器正常运行所依赖的其它库和服务. 在本例中,控制器依赖于 application-configuration,customersService 以及 alertsServices 这些功能. 这些JavaScript依赖将会通过RequireJS被动态加载进来.

AngularJS 使用了依赖注入, 因此控制器所需的所有东西都会通过参数被注入到其中. 如果你希望使用一种单元测试工具,比如Jasmine,来在你的JavaScript控制器上进行单元测试的话,这就会很有用.

$scope 对象提供了视图和控制器之间的双向数据绑定. 控制器里面再也不需要对于HTML内容的直接引用了. 控制器通过执行initializeContent函数启动,这个函数是借助内容页面中的ng-init指令被初始化的 .

客户管理页面将引用  $routeParams  服务来决定是否传入了顾客的编号. 如果是,控制器就将在customerService上执行一个getCustomer函数,该函数会向服务器发起一次AJAX调用,随后返回的JSON格式的顾客数据将会被填充到$scope属性中,继而会更新HTML模板 .

当用户点击创建按钮时,控制层会调用 createCustormer 函数。 然后,createCustormer 函数会创建一个customer类型的js对象,控制层将js对象传递给服务器,实现将数据保存到数据库中。 示例中使用了微软的WEB API、Entity Framework ,服务器端使用了 SQL Server 数据库,从技术上讲,AngularJS 可以与任意类型的数据库进行交互。

// customerMaintenanceController.js

"use strict";
define([‘application-configuration‘, ‘customersService‘, ‘alertsService‘], function (app)
{
    app.register.controller(‘customerMaintenanceController‘,
    [‘$scope‘, ‘$rootScope‘, ‘$routeParams‘, ‘customersService‘, ‘alertsService‘,

    function ($scope, $rootScope, $routeParams, customerService, alertsService)
    {
        $scope.initializeController = function () {

            var customerID = ($routeParams.id || "");

            $rootScope.alerts = [];
            $scope.CustomerID = customerID;

            if (customerID == "") {
                $scope.CustomerCode = "";
                $scope.CompanyName = "";
                $scope.Address = "";
                $scope.City = "";
                $scope.Region = "";
                $scope.PostalCode = "";
                $scope.CountryCode = "";
                $scope.PhoneNumber = ""
                $scope.WebSiteURL = "";

                $scope.EditMode = true;
                $scope.DisplayMode = false;
                $scope.ShowCreateButton = true;
                $scope.ShowEditButton = false;
                $scope.ShowCancelButton = false;
                $scope.ShowUpdateButton = false;

            }
            else
            {
                var getCustomer = new Object();
                getCustomer.CustomerID = customerID;
                customerService.getCustomer(getCustomer,
                                $scope.getCustomerCompleted,
                                $scope.getCustomerError);
            }

        }

        $scope.getCustomerCompleted = function (response) {

            $scope.EditMode = false;
            $scope.DisplayMode = true;
            $scope.ShowCreateButton = false;
            $scope.ShowEditButton = true;
            $scope.ShowCancelButton = false;
            $scope.ShowUpdateButton = false;

            $scope.CustomerCode = response.Customer.CustomerCode;
            $scope.CompanyName = response.Customer.CompanyName;
            $scope.Address = response.Customer.Address;
            $scope.City = response.Customer.City;
            $scope.Region = response.Customer.Region;
            $scope.PostalCode = response.Customer.PostalCode;
            $scope.CountryCode = response.Customer.Country;
            $scope.PhoneNumber = response.Customer.PhoneNumber;
            $scope.WebSiteURL = response.Customer.WebSiteUrl;
        }

        $scope.getCustomerError = function (response) {
            alertsService.RenderErrorMessage(response.ReturnMessage);
        }

        $scope.createCustomer = function () {
            var customer = $scope.createCustomerObject();
            customerService.createCustomer(customer,
                                            $scope.createCustomerCompleted,
                                            $scope.createCustomerError);
        }

        $scope.createCustomerCompleted = function (response, status) {

            $scope.EditMode = false;
            $scope.DisplayMode = true;
            $scope.ShowCreateButton = false;
            $scope.ShowEditButton = true;
            $scope.ShowCancelButton = false;
            $scope.CustomerID = response.Customer.CustomerID;

            alertsService.RenderSuccessMessage(response.ReturnMessage);

            $scope.setOriginalValues();
        }

        $scope.createCustomerError = function (response) {
            alertsService.RenderErrorMessage(response.ReturnMessage);
            $scope.clearValidationErrors();
            alertsService.SetValidationErrors($scope, response.ValidationErrors);
        }

        $scope.createCustomerObject = function () {

            var customer = new Object();

            customer.CustomerCode = $scope.CustomerCode;
            customer.CompanyName = $scope.CompanyName;
            customer.Address = $scope.Address;
            customer.City = $scope.City;
            customer.Region = $scope.Region;
            customer.PostalCode = $scope.PostalCode;
            customer.Country = $scope.CountryCode;
            customer.PhoneNumber = $scope.PhoneNumber;
            customer.WebSiteUrl = $scope.WebSiteURL;

            return customer;
        }

        $scope.clearValidationErrors = function () {
            $scope.CustomerCodeInputError = false;
            $scope.CompanyNameInputError = false;
        }

    }]);
});

Controller As 语法

示例中,显示层和控制层使用 $scope 技术实现 web应用和数据库的双向绑定。在上面的控制层代码中,你可以看到很多地方都使用了 $scope 对象。 在 AngularJS 中,这是实现数据绑定比较常见的方式。 AngularJS 控制层代码近期进行了细微的、影响比较大的优化。

最新的趋势是使用 Controller as ControllerName 这样的语法,而不是直接将$scope注入到你的控制器中。例如,客户管理控制器可以像如下视图中这样被引用:

<div ng-controller="customerController as customer">
<input ng-model="customer.FirstName" type="text" style="width: 300px" />
<input ng-model="customer.LastName" type="text" style="width: 300px" />
<div>
<button class="btn btn-primary btn-large" ng-click="createCustomer()"/>Create</button>
</div>

填充数据绑定属性的控制器语法就可以像下面这样:

this.FirstName = "";
this.LastName = "";

使用 "this" 对象来引用控制器的scope看上去比直接将$scope注入到控制器中更加清晰。这里需要重申,$scope是“经典”技术,而“controller as"则是AngularJS里更加新晋的东西. 它们俩都能能工作得很好,不管是选择哪一种技术,都要记用着方便为出发点. 现有的实例更多使用的是$scope,而”controller as“则正在慢慢红火起来. 其中一个会比另外一个好么?这我们就得等待并观察AngularJS随时间发生的演变.

自定义服务 - AngularJS 服务

AngularJS 服务是可替换的对象,这些对象使用依赖注入连接在一起。 在程序里,你可以使用服务来组织和共享你的代码。 AngularJS 服务是延迟初始化的 – 只有当应用程序组件依赖它时,AngularJS 才会初始化一个服务。

AngularJS 服务是单例类型 – 依赖服务的每个组件都会引用AngularJS 服务工厂类产生的一个实例。 虽然AngularJS 提供一些常用的服务(如$http),但是对于大多数应用来说,你可能想要创建自己的服务。

客户管理控制器依赖于 CustomerService. 这个顾客服务组件被应用程序用于组织所有访问和向应用程序服务器传递顾客相关数据所需要的Web API路由. 为了保持示例应用程序所有控制器中路由的清晰, 我为每一个部分(包括客户、订单、产品)都创建了服务层. AngularJS 服务能帮助你组织好你的JavaScript,以获得更好的重用性和可维护性.

顾客服务引用了由控制器设置的回调函数. 这个回调函数会在服务器调用完成时执行. 如你所能看见的,客户服务没有执行向服务器发起HTTP调用的实际工作。在定义语句中,则会依赖对将会被动态加载进来的ajaxService.

// customerService.js

define([‘application-configuration‘, ‘ajaxService‘], function (app) {

    app.register.service(‘customersService‘, [‘ajaxService‘, function (ajaxService) {

        this.importCustomers = function (successFunction, errorFunction) {
            ajaxService.AjaxGet("/api/customers/ImportCustomers",
                successFunction, errorFunction);
        };

        this.getCustomers = function (customer, successFunction, errorFunction) {
            ajaxService.AjaxGetWithData(customer, "/api/customers/GetCustomers",
                successFunction, errorFunction);
        };

        this.createCustomer = function (customer, successFunction, errorFunction) {
            ajaxService.AjaxPost(customer, "/api/customers/CreateCustomer",
                successFunction, errorFunction);
        };

        this.updateCustomer = function (customer, successFunction, errorFunction) {
            ajaxService.AjaxPost(customer, "/api/customers/UpdateCustomer",
                successFunction, errorFunction);
        };

        this.getCustomer = function (customerID, successFunction, errorFunction) {
            ajaxService.AjaxGetWithData(customerID, "/api/customers/GetCustomer",
                successFunction, errorFunction);
        };

    }]);

});

AJAX 服务

为本应用程序所创建的AJAX服务将会被所有的HTTP请求重用。AJAX 服务使用了AngularJS 的 $http 服务 , 该服务会实际执行面向服务器的 HTTP GET 和 POST 调用. 服务器调用的则是 RESTful 服务,返回的是简单的 JSON 对象.
       
AJAX 服务还使用了blockUI在HTTP请求进行时使用UI来阻塞用户的交互. 此外你还可以应用安全功能来检查用户是否已经被认证. 此应用程序使用了Forms Authentication,它会在每一个请求时附带向服务器发送一个认证的token. 我已经添加了一行代码,通过检查来自服务器的响应消息中一个普通的IsAuthenicated 属性,来看看用户是否仍然是通过认证的.

如果session已经超时,则对IsAuthenicated的检查会将用户路由到登陆页面. 让一个AJAX服务成为管理你所有的AJAX调用的中心,可以使得对整个应用程序的AJAX调用功能的实现和修改变得容易起来.

// ajaxService.js

define([‘application-configuration‘], function (app)
{
    app.register.service(‘ajaxService‘, [‘$http‘, ‘blockUI‘, function ($http, blockUI) {
        this.AjaxPost = function (data, route, successFunction, errorFunction) {
            blockUI.start();
            setTimeout(function () {
                $http.post(route, data).success(function
                          (response, status, headers, config)
                {
                    blockUI.stop();
                    successFunction(response, status);
                }).error(function (response) {
                    blockUI.stop();
                    if (response.IsAuthenicated == false)
                    {
                        window.location = "/index.html";
                    }
                    errorFunction(response);
                });
            }, 1000);
        }

        this.AjaxGet = function (route, successFunction, errorFunction) {
            blockUI.start();
            setTimeout(function () {
                $http({ method: ‘GET‘, url: route }).success(
                function (response, status, headers, config) {
                    blockUI.stop();
                    successFunction(response, status);
                }).error(function (response) {
                    blockUI.stop();
                    if (response.IsAuthenicated == false)
                    {
                        window.location = "/index.html";
                    }
                    errorFunction(response);
                });
            }, 1000);
        }

        this.AjaxGetWithData = function (data, route, successFunction, errorFunction) {
            blockUI.start();
            setTimeout(function () {
                $http({ method: ‘GET‘, url: route, params: data }).success(
                function (response, status, headers, config) {
                    blockUI.stop();
                    successFunction(response, status);
                }).error(function (response) {
                    blockUI.stop();
                    if (response.IsAuthenicated == false)
                    {
                        window.location = "/index.html";
                    }
                    errorFunction(response);
                });
            }, 1000);
        }

    }]);
});

用于AJAX服务的额外配置

在application-configuration.js文件中,加入了用于AJAX服务器请求的额外配置. 为了配置AngularJS 每次请求传递Forms Authentication的 cookie 信息, $httpProvider 会需要一个用于让 withCredentials 属性被设置为true的值.

在http连接中,AngularJS 不默认返回一个XMLHttpRequest对象,但是你可以在$httpProvider服务里配置。 当浏览器请求中含有一些阻塞UI展示的配置项时,你可以使用blockUI组件,实现在前台展示自定义的消息。

// application-configuration.js

app.config(function ($httpProvider) {
    $httpProvider.defaults.headers.common[‘X-Requested-With‘] = ‘XMLHttpRequest‘;
    $httpProvider.defaults.withCredentials = true;
});
app.config(function (blockUIConfigProvider) {
    // Change the default overlay message
    blockUIConfigProvider.message("executing...");
    // Change the default delay to 100ms before the blocking is visible
    blockUIConfigProvider.delay(1);
    // Disable automatically blocking of the user interface
    blockUIConfigProvider.autoBlock(false);
});

在每个页面请求中进行身份验证

在示例中,indexController控制前台页面的展示。 基于这一点,加载配置项时,我在application-configuration.js中定义indexController。这样,在应用程序运行之前,indexController和AngularJS一起被加载、注册。 大型的网页应用中,对于每个页面的请求,通常优先进行身份验证、授权。 为了解决这个问题,indexController包含一个函数,实现在每个页面请求前,对用户身份进行验证。

AngularJS 可以配置、监听客户端页面上用户触发的事件。 其中一个事件是$routeChangeStart。 每次请求路由定位时,都会触发这个事件。 为了使监听器工作,你只需使用$scope.$on指令配置下这个事件。

由于indexController 控制页面的跳转,因此可以在indexController 里配置$routeChangeStart 事件。在下面的示例中,为了判断用户是否被授权,浏览器在页面请求前优先执行了一个http get请求。 如果返回的isAuthenicated值为false,浏览器会跳转到登陆页面。 另外,你可以进行额外的安全性检查来判断用户是否有权限访问请求的页面。

// indexController.js

var indexController = function ($scope, $rootScope, $http, $location, blockUI) {

    $scope.$on(‘$routeChangeStart‘, function (scope, next, current) {
        $scope.authenicateUser($location.path(),
                $scope.authenicateUserComplete, $scope.authenicateUserError);
    });

    $scope.authenicateUser = function (route, successFunction, errorFunction) {
        var authenication = new Object();
        authenication.route = route;
        $scope.AjaxGet(authenication, "/api/main/AuthenicateUser",
                successFunction, errorFunction);
    };

    $scope.authenicateUserComplete = function (response) {
        if (response.IsAuthenicated==false)
        {
            window.location = "/index.html";
        }
    }

};

AngularJS $rootScope

在AngularJS里面,每个应用程序都有一个单独的root scope. 所有其他scope都是root scope的衍生物. Scope隔离了模型和视图. 你可以将属性设置在$rootScope之下,这些属性在外壳页面(shell page)的生存周期内一直保留其属性值. 只要用户刷新了浏览器,$rootScope的值就会消失,必须要重新设置.
       
当示例应用程序初始化加载的时候,它使用$rootScope保存从服务器返回的菜单选项.在用户登录后,拓展后的菜单选项列表将会从服务器返回,它允许用户访问应用程序的其它部分.$rootScope是一个很好的用来保存菜单选项等会话级别信息的地方.

  

$rootScope.MenuItems = response.MenuItems;

在外壳页面(shell page), 菜单项是数据绑定到无序列表的,在每个页面请求时保持设定的状态.

<div class="navbar-collapse collapse" id="MainMenu">
<ul class="nav navbar-nav" ng-repeat="menuItem in MenuItems">
    <li> <a href="{{menuItem.Route}}">{{menuItem.Description}} </a> </li>
</ul>
</div>
时间: 2024-12-21 03:23:34

[译]用AngularJS构建大型ASP.NET单页应用(二)的相关文章

[译]用AngularJS构建大型ASP.NET单页应用(一)

原文地址:http://www.codeproject.com/Articles/808213/Developing-a-Large-Scale-Application-with-a-Single 渣译,各位看官请勿喷 引言: ... 单页面应用程序(SPA),被定义为在一个独立的页面上??提供类似于桌面应用程序级用户体验为目标的网站.在SPA, 基本上所有的代码 - 例如 HTML,JavaScript和CSS - 都是在响应用户操作时动态加载的.页面没有在任何时候被重新刷新,也没有跳转到另一

[译]用AngularJS构建大型ASP.NET单页应用(三)

原文地址:http://www.codeproject.com/Articles/808213/Developing-a-Large-Scale-Application-with-a-Single AngularUI 下面的示例中使用了AngularUI的各种UI组件.AngularUI 是AngularJS 框架的一个辅助套件.示例中使用的主要组件大部分来在AngularUI 的一个子集UI Bootstrap.UI Bootstrap是从Twitter Bootstrap派生出来的,它使用A

AngularJS开发指南16:AngularJS构建大型Web应用详解

AngularJS是由Google创建的一种JS框架,使用它可以扩展应用程序中的HTML功能,从而在web应用程序中使用HTML声明动态内容.在该团队工作的软件工程师Brian Ford近日撰写了一篇blog,分享了如何使用AngularJS构建大型Web应用的经验.这些经验对于使用其他JS框架构建大型应用的开发者也极具借鉴意义. 这篇blog特别关注的是大型应用程序,作者首先给出的建议是,尽量不要让应用变得太巨大.而应该编写小型.功能专注的.模块化的部分,然后逐渐把它们组合起来,变得越来越大,

(译) 在AngularJS中使用的表单验证功能【转】

验证功能是AngularJS里面最酷炫的功能之一,它可以让你写出一个具有良好用户体验的Web应用. 在AngularJS中,有许多用于验证的指令.我们将先学习几个最流行的内置指令,然后再创建一个自定义验证规则的指令. <form name="form"> <label name="email">Your email</label> <input type="email" name="email&

使用 AngularJS 开发一个大规模的单页应用(SPA)

本文的目标是基于单页面应用程序开发出拥有数百页的内容,包括认证,授权,会话状态等功能,可以支持上千个用户的企业级应用. 下载源代码 介绍 (SPA)这样一个名字里面蕴含着什么呢? 如果你是经典的Seinfeld电视秀的粉丝,那么你一定知道Donna Chang这个名字.Jerry跟Donna见面,Donna其实不是华人,但是却因在谈论其对中国的固有印象比如在针灸上的兴趣,以及偶然的一次单词发音带上了点儿中文口音,她将自己末尾的名字缩成了Chang Donna 在电话上同George的母亲交谈,(

前端单页应用微服务化解决方案2 - Single-SPA

技术选型 经过各种技术调研我们最终选择的方案是基于 Single-SPA 来实现我们的前端微服务化. Single-SPA 一个用于前端微服务化的JavaScript前端解决方案 使用Single-SPA之后,你可以这样做: (兼容各种技术栈)在同一个页面中使用多种技术框架(React, Vue, AngularJS, Angular, Ember等任意技术框架),并且不需要刷新页面. (无需重构现有代码)使用新的技术框架编写代码,现有项目中的代码无需重构. (更优的性能)每个独立模块的代码可做

[Angularjs]asp.net mvc+angularjs+web api单页应用

小分享:我有几张阿里云优惠券,用券购买或者升级阿里云相应产品最多可以优惠五折!领券地址:https://promotion.aliyun.com/ntms/act/ambassador/sharetouser.html?userCode=ohmepe03 写在前面 最近的工作一直在弄一些h5的单页应用,然后嵌入到app的webview中.之前一直在用angularjs+html+ashx的一套东西.实在是玩腻了.然后就尝试通过asp.net mvc的方式构建单页应用.用到的技术angularjs

[Angularjs]asp.net mvc+angularjs+web api单页应用之CRUD操作

写在前面 前篇文章整理了angularjs学习目录,有园子里的朋友问我要这方面的demo,周末也没什么事,就在之前的单页应用的demo上面添加了增删改查的操作.代码比较简单,这里只列举比较重要的代码片段.完整的代码将在文章下面提供链接. demo 数据来源通过webapi的方式提供.获取对产品的查询,分页,增加商品,删除,修改等操作. webapi using Newtonsoft.Json; using System; using System.Collections.Generic; usi

使用 AngularJS 从零构建大型应用

0.导言 1.准备工作 2.构建框架 3.丰富你的directives 4.公用的services 5.用controllers组织业务 导言 纵览线上各种AngularJS教程,大部分都是基础与一些技巧分析. 如果你已经能运行你的ng-app,但又找不到实际案例可以参考.那么本文应该对您有所帮助. 本文将以电商产品:友好速搭 其中的 店铺后台 作为的实际案例,裸奔展示如何从零构建 “自以为大型的” AngularJS应用. 应用基于AngularJS 1.2.24版本. 准备工作 1.我们使用