Angular 1.4 newRouter 基础入门
本文介绍了 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 工作。一旦找到解决方案,我会更新文档。