在先前的步骤中,我们看到了一个控制器和一个模板如何一起工作来将一个静态的HTML文件转化为动态页面(view)。一般说来,这在单页应用中一种非常常见的模式(在Angular应用中尤其是这样):

  ·客户端代码“掌管”并和视图层实现了动态交互,通过在数据模型和状态中即刻更新视图来反应改变,这经常是用户交互的结果(我们不久将在第5步中看到一个例子),这种做法取代了在服务端创建一个静态HTML页面的做法。

模板(视图层包含绑定和展示逻辑的部分)作为一个蓝图,以此来决定我们数据怎么组织和展示给用户。而控制器提供了执行绑定和在我们的模板中申请行为和逻辑的环境(context)。

应用中依然有几个可以做得更好的地方:

  1.要是我们想在我们应用的不同部分复用相同的功能,怎么做呢?

  我们可能得复制整个模板(包括控制器)。这样做容易出错并且会降低可维护性。

  2.作用域,这被用于将我们的控制器和模板粘合到一起形成一个动态页面,不是从页面的其他部分中分离出来的。这意味着在我们的视图层中,页面不同部分的一个随机,不相关的改变可能导致不可预料且很难debug的副作用。

  (好吧,可能对于我们这小小的范例不用关心这些,但当面临一个更大,真正的应用时这些考虑是合理的。)

  这一步中最大的不同将会在下面列出。您也可以点击这里在GitHub上查看全部的不同。

组件救援!

既然这种组合(模板+控制器)是如此公共和常见的模式,Angular提供了一种简单且优雅的方式来将它们组合成可复用且独立的实体,这被称为组件。另外,Angular为我们组件中的每一个实体创建了一个所谓的isolate作用域,这意味着应用中不再有原型继承,并且我们的组件不会影响应用中的其他部分,反之亦然。

(由于这是一份介绍性的tutorial,我们不会深入介绍Angular 组件的所有特性。您可以通过阅读开发者手册的组件部分来进一步了解组件及其使用模式。

实际上,一种观点认为组件其孪生兄弟的武断(opinionated),精简的(stripped-down)版本,这个孪生兄弟更为复杂和冗余(但确实很有效)--指令,这是用Angular的方式来教会HTML的新把戏,你可以阅读开发者手册的指令部分

注:指令是一个高级话题,所以您可能得延迟学习它们知道您精通了基础部分。)

我们使用Angular模块中的.component()方法来创建一个组件。我们必须提供组件的名字和组件定义对象(Component Definition Object,缩写为CDO)。

请牢记(这点组件和指令一样)组件的名字使用驼峰命名(camelCase),但在我们的HTML中引用它的时候将会使用串联命名法(kebab-case)。

用最简单的形式,CDO将会仅仅包含一个模板和一个控制器。(我们甚至可以省略控制器,Angular会为我们创建一个傀儡控制器,这对于简单的“展示用的”组件是可以的,那将不对模板附加任何行为。)

来看个例子吧:

angular.
module('myApp').
component('greetUser', {
template: 'Hello, {{$ctrl.user}}!',
controller: function GreetUserController() {
this.user = 'world';
}
});

现在,每次我们在视图层引入<greet-user></greet-user> ,Angular将会使用提供的模板将其扩展成一棵DOM字数并且通过制定的控制器实体来管理它。

不过等等,这个$ctrl是哪来的?它又指向哪里?

由于一些已经提及的理由(还有一些已经超出本tutorial范围的理由),避免直接使用作用域(scope)被认为是一次最佳实践。我们可以(而且应该)使用我们的控制器实体;比如将我们的数据和方法分配到我们控制器中(这里“this”包含在控制器构造器中),而不是直接分配给控制器。

我们可以通过别名来从模板中引用控制器。这次,解析我们表达式的环境就更为明了了。默认地,组件使用$ctrl作为控制器的别名,但我们可以在需要的时候重载它。

还有更多可选的操作,所以在您的应用中使用.component()之前请确保您查看过API参考手册

使用组件

既然我们已经知道如何创建组件了,让我们用刚刚学习的技能来重构HTML页面吧。

app/index.html:

<html ng-app="phonecatApp">
<head>
...
<script src="bower_components/angular/angular.js"></script>
<script src="app.js"></script>
<script src="phone-list.component.js"></script>
</head>
<body> <!-- Use a custom component to render a list of phones -->
<phone-list></phone-list> </body>
</html>

app/app.js:

// Define the `phonecatApp` module
angular.module('phonecatApp', []);

app/phone-list.component.js:

// Register `phoneList` component, along with its associated controller and template
angular.
module('phonecatApp').
component('phoneList', {
template:
'<ul>' +
'<li ng-repeat="phone in $ctrl.phones">' +
'<span>{{phone.name}}</span>' +
'<p>{{phone.snippet}}</p>' +
'</li>' +
'</ul>',
controller: function PhoneListController() {
this.phones = [
{
name: 'Nexus S',
snippet: 'Fast just got faster with Nexus S.'
}, {
name: 'Motorola XOOM™ with Wi-Fi',
snippet: 'The Next, Next Generation tablet.'
}, {
name: 'MOTOROLA XOOM™',
snippet: 'The Next, Next Generation tablet.'
}
];
}
});

没错!输出的结果看起来是一样的,但让我们来看看我们收获了什么:

  ·我们的电话列表是可复用的,将 <phone-list></phone-list>放到页面的任何地方都可以获取一个电话列表。

  ·我们的主视图层(index.html)更加干净而且更具声明性了,仅仅通过查看它,我们就知道里边有一个电话列表。我们不用费心去考虑实现细节。

  ·从“外联影响(external influence)”看来,我们的组件是独立且安全的。同样的,我们不必担心意外地破坏了应用中的其他部分。我们组件中发生的故事依然待在我们的组件内。

  ·独立测试我们的组件变得更容易了。

关于文件命名的一点注解:

通过文件名前缀来区分不同类型的实体是一个好的实践。在这个tutorial中,我们使用.component前缀来表示组件,所以定义某个组件的名字会被命名为some-component.component.js.

总结

您已经学会如何组织您的应用和如何将展示层逻辑引入独立可复用的组件中。让我们进入下一步来看看怎样在我们的目录和文件中组织代码,以在应用扩展的情况下,保持代码的易定位性(easy to locate)。

[Angular Tutorial] 3-Components的更多相关文章

  1. [Angular 2] Angular 2 Smart Components vs Presentation Components

    Both Smart Components and Presentation Components receive data from Services in entirely different w ...

  2. [Angular Tutorial]PhoneCat Tutorial App

    (注:曾经在<不敢止步>一书中看到学到一个观点,作者认为学习一门技术最好的方法就是翻译某部领域书籍.这里我决定做一次尝试,接下来花1个月左右时间,将Angular Tutorial Pho ...

  3. Angular 2 to Angular 4 with Angular Material UI Components

    Download Source - 955.2 KB Content Part 1: Angular2 Setup in Visual Studio 2017, Basic CRUD applicat ...

  4. [Angular Tutorial] 4 - Directory and File Organization

    在这一步中,我们将不会在我们的应用中添加任何新功能,相反,我们打算退回一步,重构我们的代码库,移动我们的代码和文件,以此来使我们的应用更具易扩展性和可维护性. 在先前的步骤中,我们已经见识到了如何将我 ...

  5. [Angular Tutorial] 7-XHRs & Dependency Injection

    我们受够了在应用中用硬编码的方法嵌入三部电话!现在让我们用Angular内建的叫做$http的服务来从我们的服务器获取更大的数据集吧.我们将会使用Angular的依赖注入来为PhoneListCtrl ...

  6. [Angular Tutorial] 6-Two-way Data Binding

    在这一步中,您将会添加一个新特性来使得您的用户可以控制电话列表中电话的顺序,动态改变顺序是由创建一个新的数据模型的特性实现的,将它和迭代器绑定在一起,并且让数据绑定神奇地处理下面的工作. ·除了搜索框 ...

  7. [Angular Tutorial] 0-Bootstraping

    在这一节的tutorial中,您将会逐渐熟悉AngularJS phonecat app的最重要的源代码文件.您也将学到如何将开发服务器与angular-seed绑定到一起,并且在浏览器中运行应用. ...

  8. [Angular] Communicate Between Components Using Angular Dependency Injection

    Allow more than one child component of the same type. Allow child components to be placed within the ...

  9. [Angular Tutorial] 14 -Animations

    在这一步中,我们将会通过在我们先前创建的模板代码中添加CSS和JavaScript动画效果来扩展我们的web应用. ·我们现在使用ngAnimate模块来允许动画效果贯穿整个应用. ·我们也依赖于自带 ...

随机推荐

  1. odd or even?

    public boolean isEven(int data){ if((data&1)== 0) return true; return false; } much faster than ...

  2. Android消息提示框Toast

    Android消息提示框Toast Toast是Android中一种简易的消息提示框.和Dialog不一样的是,Toast是没有焦点的,toast提示框不能被用户点击,而且Toast显示的时间有限,t ...

  3. 穿越泥地(mud)

    穿越泥地(mud) 题目描述 清早6:00,FJ就离开了他的屋子,开始了他的例行工作:为贝茜挤奶.前一天晚上,整个农场刚经受过一场瓢泼大雨的洗礼,于是不难想象,FJ现在面对的 是一大片泥泞的土地.FJ ...

  4. 可信执行环境(TEE)介绍

    可信执行环境(TEE)是Global Platform(GP)提出的概念.针对移动设备的开放环境,安全问题也越来越受到关注,不仅仅是终端用户,还包括服务提供者,移动运营商,以及芯片厂商.TEE是与设备 ...

  5. PAT (Advanced Level) 1069. The Black Hole of Numbers (20)

    简单题. #include<cstdio> #include<cstring> #include<cmath> #include<vector> #in ...

  6. CG之菲涅尔效果简单实现

    菲涅尔效果,指当光到达两种材质的接触面时,一些光在接触面的表面被反射出去,而另一部分光将发生折射穿过接触面. 现在要用shader来实现这种效果,如果要精确地描述这种底层的物理,其计算公式是非常复杂的 ...

  7. bootstrap-table 表头和内容对不齐解决办法

    偶然机会学习bootstrap,表格利用bootstrap-table实现,使用bootstrap-table过程中,发现了一个非常棘手的问题,在ie浏览器中,表格的表头和内容对不齐,特别是列比较多且 ...

  8. Problem - D - Codeforces Fix a Tree

    Problem - D - Codeforces  Fix a Tree 看完第一名的代码,顿然醒悟... 我可以把所有单独的点全部当成线,那么只有线和环. 如果全是线的话,直接线的条数-1,便是操作 ...

  9. webpack.config.js 参数简单了解

    webpack.config.js文件通常放在项目的根目录中,它本身也是一个标准的Commonjs规范的模块. var webpack = require('webpack'); module.exp ...

  10. C语言常见命名规范

    C语言常见命名规范   1 常见命名规则 比较著名的命名规则首推匈牙利命名法,这种命名方法是由Microsoft程序员查尔斯·西蒙尼(Charles Simonyi) 提出的.其主要思想是“在变量和函 ...