angular companent 组件

在angularjs中,Component是一种特殊的directive,更适合组件化的app架构javascript

Component的优势:css

  • 比普通directive要简单不少
  • 更加严谨,更加规范化
  • 更加适合组件化架构
  • component更容易升级到angular2

不使用Component的状况java

  • 须要在编译阶段和预连接阶段执行的directive,由于Component这时还不可用
  • 当你须要directive才有定义的选项时,如priority, terminal, multi-element
  • 当你须要directive由属性,css的class而不是元素触发时

component的建立与配置angularjs

Components由angularjs的module使用.component()方法注册。这个方法接受2个参数:api

  • Component的名称(字符串类型)
  • Component的配置对象(注意,和.directive()不同,不是一个工厂方法而仅仅是个配置对象)

Directive和Component之间的定义比较

属性 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只能控制它本身的视图和数据:Component不会修改它自身scope以外的任何数据或DOM。一般状况下,AngularJS中能够经过scope继承和watch能够修改任何地方的数据,这确实很实用,可是也会致使很难明确哪一个部分对修改数据负责。这就是为何Component使用隔离范围,也所以没法进行全部scope的操做。
  • 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。

所以在<绑定后不要在component内修改对象的属性和数组的元素

=

使用=进行双向数据绑定,任何一方的值改变都会反应到另外一方。由于是双向绑定,因此不要使用{{}},否则会报错。

属性要用-链接,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时必定要当心。

Component做为route模版

当使用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 })
相关文章
相关标签/搜索