组件是构成angular应用的核心,angular的有序运行依赖于组件的协同工作,组件之于angular应用就像是汽车和汽车零部件的意思。
近几年的前端发展迅速,各种工程化的工具层出不穷:Browserify,Grunt,Gulp,Webpack等,有一些工具没等你学会,已经过时了。为了解决这个问题,W3C提出了Web Component标准。通过标准化的非侵入方式封装组件,每个组件都包含自己的HTML、CSS、JavaScript代码,并且不会对页面上的其他组件产生影响。
WebComponent标准包括如下四个重要的概念。
关于Web Componnet标准实现最好的是Chrome浏览器。
示例程序在这里就不放出了,baidu上面有。
Google官方出品的Polymer框架则比较接近WebComponent的写法,它是面向未来框架的。同样是出自Google的Angular与WebComponent也有几分相似,虽然AngularJS1.x版本也支持模板和自定义标签,但Angular的组件化程度比AngularJS1.x更加彻底,而且与WebComponent标准更接近。
Angular的组件是自描述的——可以和宿主元素交互,知道如何及何时渲染自己,可配置注入服务,有明确的Input&Output定义。所有的Angular组件都可以独立存在,这意味着任何Angular组件都可以作为根组件被引导,也可以被路由加载,或者在其他组件中使用。不过,一个组件不能单独被启动,它必须被包装到模块(NgModule)里,然后通过Bootstrap模块接口引导入口模块来启动Angular应用。
组件是Angular应用的最小逻辑单元,模块则是在组件之上的一层抽象。组件及其他部件如指令、管道、服务、路由等都可以被包含到一个模块中,外部通过引用这个模块来使用一系列封装好的功能。读者可以将Angular应用想像成一棵树,组件是这棵树的叶子,模块便是这棵树的树枝,每个Angular应用都必须要有一个根模块(树干),并且在根模块中必须通过Bootstrap指定根组件,用于启动Angular应用。
要创建一个组件需要遵循以下的步骤:
模块是在组件之上的一层抽象,组件及指令、管道、服务、路由等都能通过模块来组织。下面来看看模块及组件是如何协作的。
模块是由@NgModule装饰器来修饰的,一个angular应用只能有一个根模块,其他的模块都叫做特性模块。根模块必须用bootstrap元数据来指定启动的根组件
,然后通过bootstrapModule()方法来启动应用。
这样,你的应用就能启动起来。
NgModule的元数据主要有以下:
Angular应用由各种各样的组件组成,这些组件形成了一棵组件树,数据可以在组件树里完成交互,组件间的交互包括父子组件的交互和一些非父子关系组件的交互。组件交互就是组件通过一定的方式来访问其他组件的属性或方法,从而实现数据双向流动。
组件交互有很多种方式可供选择,非父子关系的组件可通过服务来实现数据交互通信。
angular提供了@Input和@Output来表示数据的流入和流出。被@Input修饰的变量属于输入属性,而被@Output修饰的则是输出属性,这里的“输入”“输出”是以当前组件的角度来说的。输出属性一般是以事件的形式,由EventEmitter发送出去的。
还可以在组件的元数据中使用inputs、outputs来设置输入和输出属性,所设置的值必须为字符串数组,元素的名称需要和成员变量相对应。以下代码和上述代码是等价的:
父组件的数据通过子组件的输入属性(@Input修饰的属性)流入子组件,在子组件中完成接收或拦截,以此实现了数据由上而下的传递。
父组件给子组件传递的数据也可以被子组件拦截并进行相应的处理,下面介绍两种方式,一种是setter拦截输入属性另一种是使用ngOnChanges钩子函数监听变化。
①使用setter拦截输入属性:getter和setter通常是配合使用的,用来对属性进行相关约束,setter可以对属性进行再封装处理,以避免错误的外部调用影响到内部的状态改变。如下图:
上图中的set contactObj和get contactObj是对字段_contact的一层封装,有了这层封装,就可以拦截传入的数据,避免错误的状态流入,对外,使用set contactObj这个属性来对数据进行接收,使用get contactObj这个属性来读取值。
②使用ngOnChanges来监听数据的变化:ngOnChanges用于及时响应Angular在属性绑定中发生的数据变化,该方法接收一个对象参数,包含当前值和变化前的值。ngOnChanges在ngOnInit之前,或者当数据绑定的输入属性的值发生变化时会触发。ngOnChanges是组件的生命周期钩子之一。直白点说ngOnChanges的作用就是监视@Input修饰的属性的变化的。这个钩子函数传入的参数的类型是SimpleChanges,它是angular的一个基础类。用于处理数据的前后变化,包含了两个重要的成员,分别是previousValue和currentValue,其中,前者用于获取变化前的数据,后者用于获取当前数据,如下图。
注意:ngOnChanges这个钩子函数使用在子组件中监测数据变化的(这段文字显得有一些愚蠢,但是已经写出来了,删除了怪可惜的)。
使用事件传递是子组件向父组件传递数据最常用的方式。子组件需要实例化一个用来订阅和触发自定义事件的EventEmitter类,这个实例对象是一个由装饰器@Output修饰的输出属性,当有用户操作行为发生时该事件会被触发,父组件则通过事件绑定的方式来订阅来自子组件触发的事件,即子组件触发的具体事件会被其父组件订阅到。下面这个例子展示了父组件和子组件通过事件来实现的数据传递:
父组件:
子组件:
父组件通过局部变量获取子组件的引用
如上我们在模板中使用“#”号定义了一个collect的变量,这个变量叫做模板局部变量。这个变量指向了子组件,那么在这个模板中的其他地方都可以使用这个变量引用来获取子组件公共成员和方法的权限。
父组件通过@ViewChild获取子组件的引用
模板局部变量只能在模板中使用,不能在组件类中使用,使用@ViewChild可以解决这个问题。@ViewChild()装饰器方法可以传入一个类名,也可以传入一个字符串,实现的功能都是一样的。但要注意传入字符串时需要在模板中定义好局部变量名,这个字符串必须是这个定义好的模板局部变量名。
还没写完,太晚了,明天继续吧
原文:https://www.cnblogs.com/pangjianxin/p/10882843.html