angular companent 组件

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

Component的优点:

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

不使用Component的情况

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

component的创建与配置

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

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

Directive和Component之间的定义比较

属性DirectiveComponent
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还具备的能力具体如下:

  • Component只能控制它自己的视图和数据:Component不会修改它自身scope之外的任何数据或DOM。通常情况下,AngularJS中可以通过scope继承和watch可以修改任何地方的数据,这确实很实用,但是也会导致很难明确哪个部分对修改数据负责。这就是为什么Component使用隔离范围,也因此无法进行所有scope的操作。
  • Component有明确定义的公共api-输入输出:隔离范围并不是全部,因为AngularJS是双向绑定的。如果你传一个对象到组件中,类似bindings: {item: '='},然后修改对象的属性,修改会反映到它的父组件中。但是对于component来说,component确实只是修改了它自己的scope内的数据。这样就很清晰的得知什么数据什么时候被修改。就此,component遵循一些简单的约定:

 输入  @

使用@符号可以进行单项的数据绑定,取值总是一个字符串,所以要用{{}}。

另外这也是一个单向的绑定,外部数据改变会反应到内部,但是内部数据变数据变化,外部不会变。

属性要用-连接,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: '&'
}

3、在不操作输入数据的情况下,component可以调用相应的输出事件改变输出数据。比如删除,并不是hero自己删除自己,而是通过相应的事件把自己传给父component

<editable-field on-update="$ctrl.update('location', value)"></editable-field><br>
<button ng-click="$ctrl.onDelete({hero: $ctrl.hero})">Delete</button>

4、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 })
原文地址:https://www.cnblogs.com/xwtbk/p/8867407.html