在angularjs中,Component是一种特殊的directive,更适合组件化的app架构javascript
Component的优势:css
不使用Component的状况java
component的建立与配置angularjs
Components由angularjs的module使用.component()
方法注册。这个方法接受2个参数:api
.directive()
不同,不是一个工厂方法而仅仅是个配置对象)属性 | Directive | Component |
---|---|---|
bindings | No | Yes (binds to controller) |
bindToController | Yes (default: false) | No (use bindings instead) |
compile function | Yes | NO |
controller | Yes | Yes (default function() {}) |
controllerAs | Yes (default: false) | Yes (default: $ctrl ) |
link functions | Yes | No |
multiElement | Yes | No |
priority | Yes | No |
replace | Yes (deprecated) | No |
require | Yes | Yes |
restrict | Yes | No (restricted to elements only) |
scope | Yes (default: false) | No (scope is always isolate) |
template | Yes | Yes, injectable |
templateNamespace | Yes | No |
templateUrl | Yes | Yes, injectable |
terminal | Yes | No |
transclude | Yes (default: false) | Yes (default: false) |
组件化app架构数组
component使得使用组件化架构构建app更为容易,除此以外component还具有的能力具体以下:angular2
Component有明肯定义的公共api-输入输出:隔离范围并非所有,由于AngularJS是双向绑定的。若是你传一个对象到组件中,相似bindings: {item: '='}
,而后修改对象的属性,修改会反映到它的父组件中。可是对于component来讲,component确实只是修改了它本身的scope内的数据。这样就很清晰的得知什么数据何时被修改。就此,component遵循一些简单的约定:架构
输入 | @ | 使用@符号能够进行单项的数据绑定,取值老是一个字符串,因此要用{{}}。app 另外这也是一个单向的绑定,外部数据改变会反应到内部,可是内部数据变数据变化,外部不会变。异步 属性要用-链接,scope中写它的驼峰格式。 若是没有经过@attr指定属性名称,那么本地名称要与DOM属性的名称一致。 |
< | 在1.5以后表示单向绑定,它绑定的属性在component的scope哪不会被watch, 这意味着你能够在component的scope内给属性设置一个新的值, 它并不会更新父scope里的值。可是若是父scope和component的scope引用的是同一个对象, 好比你在component修改对象的属性或者数组中的元素,这种改变仍然会反映到父scope。 所以在 |
|
= | 使用=进行双向数据绑定,任何一方的值改变都会反应到另外一方。由于是双向绑定,因此不要使用{{}},否则会报错。 属性要用-链接,scope中写它的驼峰格式。 若是没有经过@attr指定属性名称,那么本地名称要与DOM属性的名称一致。 |
|
输出 | & | 绑定的函数将做为component事件的回调函数 属性要用-链接,scope中写它的驼峰格式。 若是没有经过@attr指定属性名称,那么本地名称要与DOM属性的名称一致。 |
1 bindings: { 2 hero: '<', 3 comment: '@' 4 }
bindings: { onDelete: '&', onUpdate: '&' }
三、在不操做输入数据的状况下,component能够调用相应的输出事件改变输出数据。好比删除,并非hero本身删除本身,而是经过相应的事件把本身传给父component
<editable-field on-update="$ctrl.update('location', value)"></editable-field><br> <button ng-click="$ctrl.onDelete({hero: $ctrl.hero})">Delete</button>
四、component来决定事件执行什么(删除item仍是更新属性)
ctrl.deleteHero(hero) { $http.delete(...).then(function() { var idx = ctrl.list.indexOf(hero); if (idx >= 0) { ctrl.list.splice(idx, 1); } }); }
生命周期
$onInit()
- 在element上的全部controller构造和全部的绑定初始化以后,在element之上前缀&的函数连接以前,每个controller调用这个钩子方法。这是个给controller写一些初始化方法的好地方$onChanges(changesObj)
- 当单向绑定更新时调用,changesObj是一个hash键值对,key是已被修改的绑定属性的name,value是一个对象,格式是{ currentValue, previousValue, isFirstChange() }
,使用这个hook能够只触发组件内的更新,好比克隆绑定属性的对象以防止它被外部意外更新$doCheck()
- 在每个digest循环被调用,提供了一个机会能够在数据更改时验证或者作一些操做。任何你但愿进行的操做(好比对更改的响应)都必须经过这个hook调用。当$onChanges
被调用时,实现这个hook没什么做用。好比,好比你想实现一个深度的equal函数检查,或者检查一个Date对象时,他将会很是有用,由于这是AngularJS的变化检测器检测不到这个变化,天然$onChanges
也不会被调用。这个hook不包含任何参数,所以,若是想要检测变化,你须要存储以前的值,而后和如今的值进行比较。$onDestroy()
- 当controller包含的scope销毁时,controller会调用这个hook。使用这个hook能够释放一些外部资源,watch和事件处理程序$postLink()
- 在controller的element和子元素被连接后调用。和post-link函数相似,这个hook能够设置DOM事件的处理程序或者直接进行DOM操做。包含templateUrl指令的element不会被编译和连接,由于它们要等template异步加载。它们的编译和连接要等template完成以后才会执行。这个hook很是和angular2中的ngAfterViewInit和ngAfterContentInit两个hook相似。由于angular1和angular2编译过程的不一样,因此在anguar1升级到angular2时必定要当心。当使用ngRoute时,Component做为route的模版也是很是有用的。一个组件化的app,每个视图都是一个组件:
1 var myMod = angular.module('myMod', ['ngRoute']); 2 myMod.component('home', { 3 template: '<h1>Home</h1><p>Hello, {{ $ctrl.user.name }} !</p>', 4 controller: function() { 5 this.user = {name: 'world'}; 6 } 7 }); 8 myMod.config(function($routeProvider) { 9 $routeProvider.when('/', { 10 template: '<home></home>' 11 }); 12 })