发表于: 2019-02-16 19:46:32
1 470
今天完成的事情:
Angular中的装饰器是一个函数,它将元数据添加到类、类成员(属性、方法)和函数参数。
用法:要想应用装饰器,把它放到被装饰对象的上面或左边。
Angular 使用自己的一套装饰器来实现应用程序各部件之间的相互操作
这个地方是前面几个模块模块、指令、组件、依赖注入等从装饰器这个侧面的整理
你需要做的:
1.搞清楚理解TypeScript的装饰器的原理
2.搞清楚这里面每一个装饰器的作用,解决的什么问题,应用场景
类装饰器******
Angular 有很多装饰器,它们负责把元数据附加到类上,以了解那些类的设计意图以及它们应如何工作。
类装饰器应用于类构造函数,可以用来监视,修改或替换类定义。
类装饰器表达式会在运行时当作函数被调用,类的构造函数作为其唯一的参数。
@Component标记类作为组件并收集组件配置元数据(继承Directive)
@Directive标记类作为指令并收集组件配置元数据
声明当前类是一个指令,并提供关于该指令的元数据
@Pipe******
声明当前类是一个管道,并且提供关于该管道的元数据
@Injectable标记元数据并可以使用Injector注入器注入
声明当前类有一些依赖,当依赖注入器创建该类的实例时,这些依赖应该被注入到构造函数中。
@NgModule******
NgModule是一个装饰器函数,它接收一个用来描述模块属性的元数据对象。其中最重要的属性是:
declarations -声明本模块中拥有的视图类。(Angular有三种视图类:组件、指令和管道?。)
exports - declarations的子集,可用于其它模块的组件模板。Ps:模块导出声明
imports -本模块声明的组件模板需要的类所在的其它模块。Ps:模块导入声明
providers -服务的创建者,并加入到全局服务列表中,可用于应用任何部分。????完全没懂说啥
bootstrap -指定应用的主视图(称为根组件),它是所有其它视图的宿主。只有根模块才能设置bootstrap属性。
**属性装饰器******
属性装饰器表达式会在运行时当作函数被调用,
传入下列2个参数:
对于静态成员来说是类的构造函数,对于实例成员是类的原型对象。
成员的名字。
**@Input******
声明一个输入属性,以便我们可以通过属性绑定更新它。
**@Output******
声明一个输出属性,以便我们可以通过事件绑定进行订阅。
**@Hostbinding********把宿主元素的属性(比如CSS类)绑定到指令/组件的属性******
**@HostListener******
通过指令/组件的方法订阅宿主元素的事件
@ContentChild配置一个内容查询
@ViewChild配置一个视图查询
@ContentChildren配置多个个内容查询(返回QueryList类型)
@ViewChildren配置多个视图查询(返回QueryList类型)
参数装饰器******
参数装饰器表达式会在运行时当作函数被调用,
传入下列3个参数:
对于静态成员来说是类的构造函数,对于实例成员是类的原型对象。
成员的名字。
参数在函数参数列表中的索引。
注意参数装饰器只能用来监视一个方法的参数是否被传入。
@Inject指定依赖关系的参数装饰器(一般用来注入被标记Injectable的类)
@Optional将依赖项标记为可选的参数元数据. 如果没有找到依赖关系,注射器将提供null
@Self指定注射器只能从本身检索依赖关系****
@SkipSelf指定注射器只能从父类检索依赖关系****
@Host按照依赖关系来检索
1.Angular4指令分类
组件(Component directive):UI组件,继承于Directive;
属性指令(Attribute directive):改变组件的样式;
结构指令(Structural directive):改变DOM布局;
2.组件(Component directive)
代码实例
import { Component } from '@angular/core';
@Component({
selector: 'app-root', // 定义组件在HTML代码中匹配的标签
template: `<h1>Hello {{World}}</h1>`, // 指定组件关联的内联模板
})
export class AppComponent {
name = 'World';
}
组件的组成:@Component()里里里面的Template(HTML,CSS);以及export class组件里的属性和方法;
clipboard.png
3.属性指令(Attribute directive) :主要改变组件的样式
主要包括ngStyle 和 ngClass;
//ngStyle
<ul *ngFor="let person of people">
<li [style.color]="getColor(person.country)">
{{ person.name }} ({{person.country}})
</li>
</ul>
//ngClass
<div [ngClass]="{'text-success': person.country === 'CN'}"></div>
4.结构指令(Structural directive) :主要改变DOM的结构
主要包括ngIf 、 ngFor 和 ngSwitch;
//ngIf
<div *ngIf="person.country === 'CN'">{{ person.name }} ({{person.country}})</div>
//ngFor
<div *ngFor="let person of people">{{person.name}}</div>
//ngSwitch
<ul [ngSwitch]='person.name'>
<li *ngSwitchCase="Lily" class='text-success'>
{{ person.age}}
</li>
<li *ngSwitchCase="'Tom'" class='text-secondary'>
{{ person.age}}
</li>
<li *ngSwitchDefault class='text-primary'>
{{ person.age}}
</li>
</ul>
Angular中的模板
Angular自身提供了一套完整的模板系统,配合$scope对象和数据双向绑定机制,将页面纯静态元素经过行为、属性的添加和格式的转换,最终变成在浏览器中显示的动态页。
在模板系统中,可包含Angular的指令、数据绑定、表单控件和过滤器,同时,在处理复杂程序时,可以构建多个模板页面作用于视图层。在主页中,再通过包含(include)的方式加载这些零散的模板页。这样做的好处在于,一次定义可多处调用,增加代码的重复使用,减少维护成本。
1. 构建模板内容
① 直接在页面中添加元素和Angular指令,依赖控制器中构建的属性和方式绑定模板中的元素内容和事件,实现应用需求。
② 通过"type"类型为"text/ng-template"的<script>元素来构建一个用于绑定数据的模板,在模板内部添加数据绑定和元素的事件。
③ 通过添加元素的"src"属性,导入一个外部文件作为绑定数据的模板,在导入数据模板时,除添加"src"属性外,还需要使用"ng-include"指令。
例1:首先通过<script>元素构建了一个显示两项数据信息的模板;然后,在新增的一个<div>元素中将模板的内容导入到元素中。
<script type="text/ng-template" id="tplbase">
姓名:{{name}},<br>
邮箱:{{email}}
</script>
<div ng-include src="'tplbase'" ng-controller="fn"></div>
<script src="js/angular.min.js"></script>
<script>
var mod = angular.module('aa',[]);
mod.controller('fn',['$scope', function ($scope) {
$scope.name="zyt";
$scope.email="zouyitingRae@163.com"
}])
// 先添加一个"type"类型为"text/ng-template"的<script>元素,并在该元素中通过双花括号的方式绑定控制器中需要显示的两项数据。
// 由于该元素定义的是Angular类型的模板,因此,它可以直接使用Angular中的表达式进行数据绑定,除此之外,还可以在模板中绑定元素的各类事件
// 在完成模板内容构建之后,新添加一个<div>元素,用来导入模板内容。在导入时,首先添加"ng-include"指令,声明该元素的内容来源于其他模板;
// 然后再添加"src"属性,指定对应模块的名称,即ID号或模板文件名称。需要注意的是:"src"属性值是一个表达式,它可以是$scope中的属性名,
// 也可以是普通字符串。如果是后者,必须添加引号
</script>
2. 使用指令复制元素
在构建模板内容的过程中,有时需要反复将不同的数据加载到一个元素中,例如,通过< li>元素绑定一个数组的各成员。此时,可以使用"ng-repeat"指令,它的功能时根据绑定数组成员的数量,复制页面中被绑定的< li>元素,并在复制过程中添加元素相应的属性和方法,通过这种方式,实现数组数据与元素绑定的过程。
在使用"ng-repeat"指令复制元素的过程中,还提供了几个非常实用的专有变量,可以通过这些变量来处理显示数据时的各种状态。这些变量的功能分别如下:
--$first,该变量表示记录是否是首条,如果是则返回true,否则返回false.
--$last,该变量表示记录是否是尾条,如果是则返回true,否则返回false.
--$middle,该变量表示记录是否是中间条,如果是则返回true,否则返回false.
--$last,该变量表示记录的索引值,其对应的值从0开始.
例2:在页面中,通过< li>元素显示一个数组中的全部成员数据,并且在显示数据时列出当条数据是否是“首条”和“尾条”记录的状态信息。
<style>
body{font-size: 12px;}
ul{list-style: none;width: 400px;margin: 0;padding: 0;}
li{float: left;padding: 5px 0;}
span{width: 50px;float: left; padding: 0 10px;}
</style>
<div ng-controller="fn">
<ul>
<li>
<span>序号</span>
<span>姓名</span>
<span>性别</span>
<span>是否首条</span>
<span>是否尾条</span>
</li>
<li ng-repeat="stu in data">
<span>{{$index+1}}</span>
<span>{{stu.name}}</span>
<span>{{stu.sex}}</span>
<span>{{$first?'是':'否'}}</span>
<span>{{$last?'是':'否'}}</span>
</li>
</ul>
</div>
<script src="js/angular.min.js"></script>
<script>
var mod = angular.module('aa',[]);
mod.controller('fn',['$scope', function ($scope) {
$scope.data=[
{name:'赵四',sex:'女'},
{name:'张三',sex:'男'},
{name:'王二',sex:'男'},
]
}]);
</script>
3. 添加元素样式
① 直接绑定值为CSS类别名称的$scope对象属性
例:$scope.red="red";
<div class="{{red}}"></div> === <div ng-class="{{red}}"
② 以字符串数组方式选择性添加CSS类别名称
例:$scope.blnfocus=true;
<div ng-class="{true:'red',false:'blue'}[blnfocus]"></div>
<div>的CSS样式取决与"blnfocus"属性值,当该值为true时,添加“red”样式名,当该值为false时,添加“blue”样式名。这种方式只能在两种样式中选择一种,并且{}和[]顺序不可颠倒。在{}中设置可选择的两种样式名称,在[]中设置控制样式的的属性名。
③ 通过定义key/value对象的方式来添加多个CSS类别名称
例:$scope.a=false;
$scope.b=true;
<div ng-class="{'red':a,'blue':b}"></div>
此外,在Angular中,还有另外两个用于添加样式的页面指令,分别为"ng-class-odd"和"ng-class-even"专用于以列表方式显示数据,对应奇数行和偶数行的样式。
例3:在例2的基础上,在样式方面增加三个功能,首先,将第一个< li>元素中显示的字体加粗;其次,添加"ng-class-odd"和"ng-class-even"两个指令,实现列表的隔行变色功能;最后,当单击某行< li>的元素时,显示相应的背景色。
<style>
body{font-size: 12px;}
ul{list-style: none;width: 408px;margin: 0;padding: 0;}
li{float: left;padding: 5px 0;}
ul .odd{color: #0026ff;}
ul .even{color: #f00;}
ul .focus{color: #ccc;}
ul .bold{font-weight: bold;}
span{width: 52px;float: left; padding: 0 10px;}
</style>
<div ng-controller="fn">
<ul>
<li ng-class="{{bold}}">
<span>序号</span>
<span>姓名</span>
<span>是否首条</span>
<span>是否尾条</span>
</li>
<li ng-class-odd="'odd'" ng-class-even="'even'" ng-repeat="stu in data" ng-click="li_click($index)" ng-class="{focus:$index==focus}">
<span>{{$index+1}}</span>
<span>{{stu.name}}</span>
<span>{{stu.sex}}</span>
<span>{{$first?'是':'否'}}</span>
<span>{{$last?'是':'否'}}</span>
</li>
</ul>
</div>
<script src="js/angular.min.js"></script>
<script>
var mod = angular.module('aa',[]);
mod.controller('fn',['$scope', function ($scope) {
$scope.bold='bold';
$scope.li_click= function (i) {
$scope.focus=i;
}
$scope.data=[
{name:赵四',sex:'女'},
{name:'张三',sex:'男'},
{name:'王二',sex:'男'},
]
}]);
</script>
4.控制元素的显示与隐藏状态
在Angular中,可以通过“ng-show”“ng-hide”“ng-switch”指令来控制元素的隐藏与显示的状态。前两个指令直接控制元素的显示与隐藏状态。当“ng-show”值为true或“ng-hide”值为false时,元素显示,反之,元素隐藏。
后一个“ng-switch”指令的功能是显示匹配成功的元素,该指令需要结合"ng-switch-when"和"ng-switch-default"指令使用。在"ng-switch"指令中,当指定的“on”值与某个或多个添加"ng-switch-when"指令的元素匹配时,这些元素显示,其他未匹配的元素则隐藏。如果没有找到与“on”值相匹配的元素时,则显示添加了"ng-switch-default"指令的元素。
例4:
<div ng-controller="fn">
<div ng-show={{isShow}}>zyt</div>
<div ng-hide={{isHide}}>zouyitingrae@163.com</div>
<ul ng-switch on={{switch}}>
<li ng-switch-when="1">zyt</li>
<li ng-switch-when="2">zouyitingrae@163.com</li>
<li ng-switch-default>更多...</li>
</ul>
</div>
<script src="js/angular.min.js"></script>
<script>
var mod = angular.module('aa',[]);
mod.controller('fn',['$scope', function ($scope) {
$scope.isShow = true;
$scope.isHide = false;
$scope.switch = 3;
}]);
</script>
明天计划的事情:(一定要写非常细致的内容)
遇到的问题:(遇到什么困难,怎么解决的)
收获:(通过今天的学习,学到了什么知识)
评论