65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 Angular ui-router 创建单页应用程序

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.80/5 (10投票s)

2016 年 9 月 20 日

CPOL

5分钟阅读

viewsIcon

25231

downloadIcon

825

本文将引导您完成使用 ui-router 创建单页应用程序的步骤。

引言

页面加载:我们都经历过。所有上网的人都知道这有多烦人,尤其是在网站速度慢的情况下。我们需要单独重新加载网站页面,这会浪费大量时间和带宽,因为每次导航页面都需要加载整个网页。然而,如今,移动用户已经习惯了使用具有移动应用功能的网站。这有助于增加我们的网站访问量。尽管如此,页面加载仍然是用户面临的一个大问题。为了解决这个问题,AngularJS 引入了路由,这样您就可以在单个父页面上加载不同的页面,而无需像移动应用程序那样加载整个网页。

在本文中,我将向您展示如何使用 AngularJS ui-router 和 Web API 2 创建一个单页应用程序。该 Web 应用将为用户提供一个仪表板面板,用户可以在其中对 Web API 执行 CRUD(创建、读取、更新、删除)操作。

Using the Code

此应用程序将显示一个学生列表表格,然后通过单击每一行,将显示详细信息,并具有编辑和更新功能。所有这些交互都发生在单个页面上,无需刷新整个页面。

在开始之前,我们需要通过 NuGet 包下载以下库。

  1. AngularJS.Core:此库包含主要的 Angular 文件。
  2. Angular.UI.UI-Router:此库与路由框架相关,用于创建单个应用程序。
  3. AngularJS.Resource:此库用于轻松地在服务器端数据(Web API 2)上执行 CRUD 操作(创建、读取、更新、删除)。

要下载上述库,请在 Visual Studio 中转到项目 > NuGet 包管理器,然后按照下面的说明安装它们。所有文件都将下载到Scripts文件夹中。

事先,我们需要知道哪个页面应该是我们的单页。在此项目中,我在 MVC 项目中的以下路径选择了一个页面。此页面是浏览器中唯一加载的页面,其余视图(页面)将加载到<ng-view>指令中作为占位符。

view\home\Index.cshtml

@{
    ViewBag.Title = "School";
}

<ui-view></ui-view>

@section scripts {

    @Scripts.Render("~/Scripts/angular.js")
    @Scripts.Render("~/Scripts/angular-resource.js")
    @Scripts.Render("~/Scripts/angular-ui-router.js")

    @Scripts.Render("~/Scripts/App/controller.js")
}

此页面继承自_Layout.cshtml,如下所示,并使用 Bootstrap 框架作为其布局。此外,所有下载的 Angular 库都应添加到此页面末尾。我们还需要添加包含我们代码的controller.js

Views\Shared\_Layout.cshtml

.
.
<div class="container body-content" ng-app="MyApp">
        @RenderBody()
        <hr />
        <footer>
            <p>&copy; @DateTime.Now.Year</p>
        </footer>
</div>
.
.

ng-app="MyApp" 用于 自动引导 AngularJS 应用程序。

让我们开始吧!首先在Script文件夹中创建一个App\Controller.js 并在文件顶部添加以下行。

var app = angular.module("MyApp", ["ngResource", "ui.router"]);

在 AngularJS 中,模块定义了一个应用程序。如上所示,我们在 app 模块中添加了两个依赖项:ui.router对于路由是必需的,而ngResource提供了将在后面解释的$resource

app.config是单页应用程序中最重要的部分。通过app.config,您可以为应用程序或模块配置状态。每个状态都有自己的名称和 URL,并且还与templateUrl和 controller 相关联,如下所示。

Scripts\App\Controller.js

.
.
app.config(function ($stateProvider, $urlRouterProvider) {

    $stateProvider

        .state("list", {
            url: "/list",
            templateUrl: "/ngView/list.html",
            controller: "listCtrl"
        })
        .state("list.detail", {
            url: "/detail/{id}",
            templateUrl: "/ngView/detail.html",
            controller: "detailCtrl"
        })
        .state("list.detail.form", {
            url: "/form",
            templateUrl: "/ngView/form.html",
            controller: "formCtrl"
        });

    // For any unmatched url, redirect to /list
    $urlRouterProvider.otherwise("/list");

});
.
.

如上所示,有三个状态和$urlRouterProvider.otherwise,用于将不匹配的 URL 重定向到 /list 状态。

url:状态通过 url 导航,并填充任何传入的参数。

templateUrl:模板文件的String URL 路径。这里,模板文件位于ngView 文件夹中,将根据状态加载到视口(<ui-view>)中。

controller:Controller 与视图相关联。在此项目中,我们有三个状态可以彼此嵌套,如下图所示。每个状态将在下面进行解释。

1) 列表

此状态负责在 HTML 表格中填充用户列表。此状态与一个控件(listCtrl)、list.html和一个url路径相关联。

listCtrlstateProvider中的状态调用时执行。它负责从服务(稍后将解释的APIService)获取数据。它还将数据绑定到List.html中的 HTML 表格,并具有另一个用于在表单中填充数据以进行编辑和更新的功能。

.
.
app.controller("listCtrl", function ($scope, APIservice) {

    APIservice.query(function (Data) {
        $scope.dataList = Data;
    });

    $scope.edit = function (id) {

       $location.path("/form/" + (id));
    }
})
.
.

ngView\list.html

<div class="row">
    <div class="col-md-12" ng-controller="listCtrl">
        <table class="table table-hover table-striped">
            <thead class="header">
                <tr>
                    <th>Name</th>
                    <th>Phone</th>
                    <th>Address</th>
                </tr>
            </thead>
            <tbody>
                <tr ng-repeat="row in dataList">
                    <td><a ui-sref=".detail({id:row.StudentId})">{{row.Name}}</a></td>
                    <td><a ui-sref=".detail({id:row.StudentId})">{{row.Phone}}</a></td>
                    <td><a ui-sref=".detail({id:row.StudentId})">{{row.Address}}</a></td>
                </tr>
            </tbody>
        </table>
    </div>
    <ui-view></ui-view>
</div>

此文件是状态列表的templateUrl,包含一个带有ng-repeat指令的 HTML 表格。文件末尾有一个占位符<ui-view>,用于加载另一个视图或 HTML 文件(子项)。

还有一个指令ui-sref,负责导航到状态,在此项目中,我们将参数传递给 detail 状态,以在占位符中显示行的详细信息。

ui-sref=".detail({id:row.StudentId})"

2) list.detail

此状态在列表的占位符(ui-view)中显示用户详细信息。请记住使用点创建父/子状态。在此状态中,List 是父项,Detail 是子项。

.
.
app.controller("detailCtrl", function ($scope, $stateParams, APIservice) {

    $scope.dataDetail = APIservice.get({ id: $stateParams.id });

});
.
.

此 Controller 负责显示由行$stateParams.id检索到的行的详细信息。

$routeParams是什么?它允许您检索当前路由parameters.$routeParams.id的集合,以帮助获取从 URL 传递的Id

ngView\detail.html

<div class="col-md-6">
    <h3>
        <b>Name:</b>{{dataDetail.Name}}
    </h3>
    <h3>
        <b>Phone:</b>{{dataDetail.Phone}}
    </h3>
    <h3>
        <b>Address:</b>{{dataDetail.Address}}
    </h3>
    <h3>
        <b>Comments:</b>{{dataDetail.Comment}}
    </h3>
    <button type="button" class="btn btn-success" 
    title="Edit" ui-sref=".form"><span></span>Edit</button>
</div>
<div class="col-md-6" style="border: 1px solid #ddd;">
    <ui-view></ui-view>
</div>

此文件负责填充用户详细信息,并有一个编辑按钮,可在其自己的占位符中调用另一个状态(Form)。

3) list.detail.form

此状态负责显示表单并填充数据以进行编辑。

Form Controller 分为两部分。第一部分是捕获参数“id”,将其传递给服务,返回数据并将其填充到表单中以进行编辑。第二部分是更新表单的功能。

.
.
app.controller("formCtrl", function ($scope, $state, $stateParams, APIservice) {

    if ($stateParams.id)

        $scope.user = APIservice.get({ id: $stateParams.id });


    $scope.submit = function (user) {

        APIservice.update({ id: $stateParams.id }, user, function () {
            $state.go("list", {}, { reload: true });
        });
    }

});
.
.

ngView\form.html

<h1>Edit</h1>


<form role="form" ng-submit="submit(user)">

    <div class="form-group">

        <label for="name">Name</label>

        <input type="text" ng-model="user.Name" class="form-control">

    </div>

    <div class="form-group">

        <label for="phone">Phone</label>

        <input type="text" ng-model="user.Phone" class="form-control">

    </div>

    <div class="form-group">

        <label for="address">Address</label>

        <input type="text" ng-model="user.Address" class="form-control">

    </div>

    <div class="form-group">

        <label for="address">Comment</label>

        <input type="text" ng-model="user.Comment" class="form-control">

    </div>

    <div class="form-group">

        <button type="submit" class="btn btn-default">Submit</button>

    </div>

</form>

此文件包含一个 HTML 表单,其中有一个在ng-model指令中定义的 User 模型。通过此指令,您可以将输入字段的值绑定到 AngularJS 中可用的变量。此表单还通过ng-submit="submit(user)将 HTML 控件(输入)的值发送到formCtrl controller。

使用 $resource

通过$resource,您的应用程序可以与数据源进行交互。这使您可以轻松地在服务器端数据(Web API)上执行 CRUD 操作(创建、读取、更新、删除)。

在此项目中,为了在 Controller 之间共享$resource,我们需要将其添加到下面提到的Service中,并将其命名为APIService

.
.
app.service("APIservice", function ($resource) {

    return $resource("/api/Students/:id", null, { "update": { method: "PUT" } });

});
.
.

结论

在此项目中,您学会了如何使用 AngularJs ui-router和数据资源(Web API 2)创建一个单页应用程序。您还学会了如何实现$resource以与 Web API 进行交互。您还可以下载源文件以获得更清晰的图景。

© . All rights reserved.