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

Angular 1.4 newRouter 基础入门

starIconstarIconstarIconstarIconstarIcon

5.00/5 (3投票s)

2015 年 3 月 30 日

CPOL

6分钟阅读

viewsIcon

47414

downloadIcon

491

本文介绍了 AngularJS 1.4 中引入的 newRouter 的基础知识。请注意,Angular 1.4 和 new router 仍在开发中,尚未正式发布。

引言

本文介绍了 AngularJS 1.4 中 newRouter 的基础知识。这个由 Angular 团队开发的路由器将成为非常流行的开源 ui-router 的替代品。

先决条件

要开始使用 newRouter,让我们创建一个网页,下载并包含所需的 JavaScript 库。

  • 使用您选择的 IDE 创建一个简单的网页
  • 创建一个名为 js 的文件夹,下载并将以下 JavaScript 文件保存在其中
  • 来自 Google CDN 的 angular-1.4.0-beta.6.js 库,地址为 AngularJ-1.4.0-beta.6
  • router.es5.js,可在 router.es5.js 获取
  • 通过创建 ng-app、module 和 controller 来添加常规的 AngularJS 内容。

遵循上述步骤后,网页应如下所示:

<!DOCTYPE html>
<html ng-app="AngularApp">
    <head>
        <title>Start Page</title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <script src="js/angular-1.4.0-beta.6.js"></script>
        <script src="js/router.es5.js"></script>
    </head>
    <body ng-controller="MainController">
        
        <h1>{{title}}</h1>
        <div ng-viewport></div>
        
        
        <script>
            var module = angular.module("AngularApp", ["ngNewRouter"]);
            module.controller("MainController", function($scope, $router){
                $scope.title = "This is demo of application";
                
            });
        </script>   
     </body>
</html>

请注意,我们注入了一个新的模块 ngNewRouter。MainController 中也注入了一个 $router。这为使用 newRouter 建立了基本的基础设施。

创建占位符:ngViewPort 指令

为了将称为组件的 HTML 模板注入网页,我们需要为其创建一个容器/占位符 div。这个 div 应该有一个 Angular 指令 ng-viewport。这个 ng-viewport 类似于 AngularJS 核心功能和 Angular UI 路由中的 ng-view/ui-view。

    ......
    <body ng-controller="MainController">
        <div ng-viewport></div>
    </body>

多个 ViewPorts/命名 ViewPorts

我们可以通过命名来创建多个占位符/viewports。这使我们能够使用不同的 HTML 模板加载屏幕的多个部分。这在使用 AngularJS 的默认路由框架 (ngRoute) 时是不可能的。

    ......
    <body ng-controller="MainController">
        <div ng-viewport="FirstViewPort"></div>
        <div ng-viewport="SecondViewPort"></div>
    </body>

稍后在讨论 URL 到组件的映射时,我们将重点介绍这一点。

定义组件

在 AngularJS 1.4 中,HTML 模板被归类为组件。每个组件都是一个可重用的集合,具有自己的名称、模块、控制器和 HTML。AngularJS 1.4 默认需要创建一个名为 components 的目录。在此目录中,我们需要为每个组件名称创建一个文件夹。每个组件目录将包含:

  • 自己的 JavaScript 文件,其中包含其模块定义、控制器以及相关的其他事件处理程序。
  • "componentname".html 文件,名为 "componentname".html
  • 任何其他 JavaScript 文件,按需添加

例如,如果我们创建一个名为 "navigation" 的组件,我们需要在 components 文件夹内创建一个名为 navigation 的文件夹。AngularJS 将通过 $router 来负责将容器和组件粘合在一起,我们稍后会看到这一点。最终的目录结构将如下所示:

 

定义组件模块

如上所述,每个组件将拥有自己的 Angular 模块。需要注意的重要一点是,为了使一切正常工作,需要遵循某些规则。

  • 组件的控制器名称应为 "CapitalizedComponentName"Controller,即名为 "navigation" 的组件的 NavigationController。
  • 为了模块化,每个组件模块都应在其自己的 js 文件中定义,位于 components 目录中,即名为 "navigation" 的组件的 navigation.js。
  • 组件模块需要作为依赖项添加到应用程序的主模块中。

 

在 navigation.js 中定义的导航示例模块将如下所示:

angular.module("AngularApp.navigation", []).controller("NavigationController", NavigationController);

// Note that the controller name is NavigationController. If we give something else, Angular wont be able to do binding.
function NavigationController() {
    // Controller bindings
}   

定义组件控制器

每个组件都将拥有自己的控制器,由 "CapitalizedComponentName"Controller 标识。有一件特别的事情需要注意,这个控制器与其他控制器略有不同。它不需要 $scope 进行双向绑定。如果我们传入 $scope,Angular 将无法实例化控制器。它在 this 上定义其可观察属性。

示例控制器将如下所示:

    // Note that the controller doesnt inject $scope.
    function NavigationController() { // Dont inject $scope. Angular wont be able to create controller.
        this.title = "Welcome"; // Binding on this not $scope
        this.options = ["Home", "My Account", "Log Out"]; // Binding on this not $scope
    }

现在,您可能会想,既然我们没有在 $scope 上添加变量,双向绑定将如何工作?我们将在下一节介绍。

定义组件视图

组件视图是一个 HTML 片段,它将被加载到其绑定的 ngViewPort div 中的 DOM 中。虽然这遵循了所有现有的 Angular 视图原则,但有一些例外:

  • 我们不需要将 ng-controller 添加到 HTML 模板中。newRouter 将自动处理这一点。
  • 在执行双向绑定时,我们需要在变量名前加上组件的名称。

 

以下是一个简单的 navigation.html。请注意,它没有任何 ng-controller,并且组件名称 "navigation" 已添加到可观察属性的前面。

    <div>{{navigation.title}}</div>
    <div>
        <ul>
        <li ng-repeat="opt in navigation.options">{{opt}}</li>
        </ul>
    </div>

使用组件

一旦组件准备好其模块、控制器和视图,就可以在主视图中使用它。这时 $router 就派上用场了。$router 提供了将 URL 映射到组件的功能。这意味着,当访问特定 URL 时,组件将被加载到 ngViewPort div 中。让我们看几个例子:

映射到单个 ViewPort

此示例演示了,如果只有一个 viewport/placeholder,当匹配的 URL 被命中时,HTML 组件会自动加载到其中。

容器 HTML 看起来像这样:

    <body ng-controller="MainController">
        <h1>{{title}}</h1>
        <div ng-viewport></div>
     </body>       

路由映射看起来像这样:

    var module = angular.module("AngularApp", ["ngNewRouter", "AngularApp.navigation"]);
            module.controller("MainController", function($scope, $router){
                $scope.title = "This is demo of application";
                $router.config([
                    {path:"/", component:  "navigation"}, // Maps the default path to navigation component.
                    {path:"/profile", component:  "profile"} // Maps /profile to navigation component.
                    
                ]);
    });
    

$router.config(...) 创建了相对路径和组件之间的映射。当 Angular 检测到 URL /(在本例中是默认值)被加载时,它会将 navigation.html 连同其控制器一起加载到 DOM 中,并将其追加到 ngViewPort div。对于 "/profile" URL,组件 profile 被加载到 viewport div 中。

映射多个 ngViewPorts

在本文开头,我们提到可以通过命名来创建多个 viewports。这允许使用不同的 HTML 模板渲染屏幕的多个部分。这解决了在给定 URL 上需要加载屏幕多个部分的用例。以下示例解释了这种类型的映射:

容器 HTML 文件看起来像这样:

    ....
   <body ng-controller="MainController">
        <h1>{{title}}</h1>
        <div ng-viewport="FirstViewPort"></div>
        <div ng-viewport="SecondViewPort"></div>
   </body>     

路由映射看起来像这样:

    var module = angular.module("AngularApp", ["ngNewRouter", "AngularApp.navigation"]);
            module.controller("MainController", function($scope, $router){
                $scope.title = "This is demo of application";
                $router.config([
                    {path:"/", component:  {FirstViewPort: "navigation", SecondViewPort: "profile"}},
                    {path:"/admin", component:  {FirstViewPort: "navigation", SecondViewPort: "admin"}},
            ]);
    });
    

上面的示例

  • 对于 URL "/",将导航组件映射到 placeholder FirstViewPort,并将 profile 组件映射到 SecondViewPort。
  • 对于 URL "/admin",将导航组件映射到 placeholder FirstViewPort,并将 profile "admin" 映射到 SecondViewPort。

 

重定向到组件

除了映射之外,newRouter 还支持将 URL 路由到组件。这意味着我们可以将默认 URL "/" 重定向到一个名为 "navigation" 的组件,从而使其成为默认屏幕组件。

以下代码片段对此进行了说明:

    var module = angular.module("AngularApp", ["ngNewRouter", "AngularApp.navigation", "AngularApp.profile", "AngularApp.admin"]);
    module.controller("MainController", function($scope, $router){
        $scope.title = "This is demo of application";
        $router.config([
            {path:"/", redirectTo: "navigation"}, // The default URL is redirected to navigation component.
            {path:"/navigation", component: "navigation"},
            {path:"/admin", component: "admin"}
        ]);
    });

链接组件 - ngLink

现在我们已经完成了创建占位符/viewports、设置组件(HTML、控制器)、将组件与单个 viewports 和多个 viewports 的 URL 映射。现在我们需要编写代码来在用户操作(如单击链接等)时调用此映射。

Angular 提供了一个特殊的指令 ngLink,它使用 <a> 的 href 属性来调用 URL 查找,以便加载 HTML 组件。这意味着当应用于 <a> 时,根据 AngularJS 文档,ngLink 会自动生成一个 href 属性,该属性会查找 $router 映射并将屏幕部分加载到定义的占位符/viewports 中。

以下示例显示了路由映射的外观:

    var module = angular.module("AngularApp", ["ngNewRouter", "AngularApp.navigation", "AngularApp.profile", "AngularApp.admin"]);
    module.controller("MainController", function($scope, $router){
        $scope.title = "This is demo of application";
        $router.config([
            {path:"/", redirectTo: "navigation"},
            {path:"/navigation", component: "navigation"},
            {path:"/admin", component: "admin"}
        ]);
    });

以下示例显示了 ngLink 的用法:

    <body ng-controller="MainController">
        <h1>{{title}}</h1>
        <a ng-link="navigation()">Home</a>
        <a ng-link="admin()">Admin</a>
        <div ng-viewport></div>
    </body>

已知问题

由于这仍在开发中,我遇到了一些问题:

1. 嵌套路由不起作用

2. ngLink 对命名 viewports 不起作用
 

摘要

在这篇文章中,我试图解释 newNgRouter 的用法,它是 Anguar 1.4 的一部分,尚未发布。我发现对于命名 viewports,我无法让 ngLink 工作。一旦找到解决方案,我会更新文档。

 

参考文献

© . All rights reserved.