Angular4_td中的colspan

<td [attr.colspan]="progressCode == 'WAITING' ? 11: 10 ">


attribute、class 和 style 绑定

模板语法为那些不太适合使用属性绑定的场景提供了专门的单向数据绑定形式。

attribute 绑定

可以通过attribute 绑定来直接设置 attribute 的值。

这是“绑定到目标属性 (property)”这条规则中唯一的例外。这是唯一的能创建和设置 attribute 的绑定形式。

本章中,通篇都在说通过属性绑定来设置元素的属性总是好于用字符串设置 attribute。为什么 Angular 还提供了 attribute 绑定呢?

因为当元素没有属性可绑的时候,就必须使用 attribute 绑定。

考虑ARIASVG和 table 中的 colspan/rowspan 等 attribute。 它们是纯粹的 attribute,没有对应的属性可供绑定。

如果想写出类似下面这样的东西,现状会令我们痛苦:

content_copy<tr><td colspan="{{1 + 1}}">Three-Four</td></tr></td></tr>

会得到这个错误:

content_copyTemplate parse errors: Can't bind to 'colspan' since it isn't a known native property (模板解析错误:不能绑定到 'colspan',因为它不是已知的原生属性)

正如提示中所说,<td>元素没有colspan属性。 但是插值表达式和属性绑定只能设置属性,不能设置 attribute。

我们需要 attribute 绑定来创建和绑定到这样的 attribute。

attribute 绑定的语法与属性绑定类似。 但方括号中的部分不是元素的属性名,而是由attr前缀,一个点 (.) 和 attribute 的名字组成。 可以通过值为字符串的表达式来设置 attribute 的值。

这里把[attr.colspan]绑定到一个计算值:

src/app/app.component.html
content_copy<table border1> <!-- expression calculates colspan=2 --> <tr><td [attr.colspan]"1 + 1">One-Two</td></tr> <!-- ERROR: There is no `colspan` property to set! <tr><td colspan="{{1 + 1}}">Three-Four</td></tr> --> <tr><td>Five</td><td>Six</td></tr> </table>

这里是表格渲染出来的样子:

One-Two
Five Six

attribute 绑定的主要用例之一是设置 ARIA attribute(译注:ARIA指可访问性,用于给残障人士访问互联网提供便利), 就像这个例子中一样:

src/app/app.component.html
content_copy<!-- create and set an aria attribute for assistive technology --> <button [aria-label]"actionName">{{actionName}} with Aria</button>

CSS 类绑定

借助CSS 类绑定,可以从元素的classattribute 上添加和移除 CSS 类名。

CSS 类绑定绑定的语法与属性绑定类似。 但方括号中的部分不是元素的属性名,而是由class前缀,一个点 (.)和 CSS 类的名字组成, 其中后两部分是可选的。形如:[class.class-name]

下列例子示范了如何通过 CSS 类绑定来添加和移除应用的 "special" 类。不用绑定直接设置 attribute 时是这样的:

src/app/app.component.html
content_copy<!-- standard class attribute setting --> <div class"bad curly special">Bad curly special</div>

可以把它改写为绑定到所需 CSS 类名的绑定;这是一个或者全有或者全无的替换型绑定。 (译注:即当 badCurly 有值时 class 这个 attribute 设置的内容会被完全覆盖)

src/app/app.component.html
content_copy<!-- reset/override all class names with a binding --> "bad curly special" [class]"badCurly">Bad curly最后,可以绑定到特定的类名。 当模板表达式的求值结果是真值时,Angular 会添加这个类,反之则移除它。

src/app/app.component.html
content_copy<!-- toggle the "special" class on/off with a property --> <div [class.special]"isSpecial">The class binding is special</div> <!-- binding to `class.special` trumps the class attribute --> "special" ["!isSpecial">This one is not so special</div>

虽然这是切换单一类名的好办法,但我们通常更喜欢使用NgClass指令来同时管理多个类名。


样式绑定

通过样式绑定,可以设置内联样式。

样式绑定的语法与属性绑定类似。 但方括号中的部分不是元素的属性名,而由style前缀,一个点 (.)和 CSS 样式的属性名组成。 形如:[style.style-property]

src/app/app.component.html
content_copystyle.color]"isSpecial ? 'red': 'green'">Red</button> background-color]"canSave ? 'cyan': 'grey'" >Save</button>

有些样式绑定中的样式带有单位。在这里,以根据条件用 “em” 和 “%” 来设置字体大小的单位。

src/app/app.component.html
content_copyfont-size.em]"isSpecial ? 3 : 1" >Bigfont-size.%]"!isSpecial ? 150 : 50" >Small</button>

虽然这是设置单一样式的好办法,但我们通常更喜欢使用NgStyle指令来同时设置多个内联样式。

注意,样式属性命名方法可以用中线命名法,像上面的一样 也可以用驼峰式命名法,如fontSize


事件绑定 ((事件名))

前面遇到的绑定的数据流都是单向的:从组件到元素。

但用户不会只盯着屏幕看。他们会在输入框中输入文本。他们会从列表中选取条目。 他们会点击按钮。这类用户动作可能导致反向的数据流:从元素到组件

知道用户动作的唯一方式是监听某些事件,如按键、鼠标移动、点击和触摸屏幕。 可以通过 Angular 事件绑定来声明对哪些用户动作感兴趣。

事件绑定语法由等号左侧带圆括号的目标事件和右侧引号中的模板语句组成。 下面事件绑定监听按钮的点击事件。每当点击发生时,都会调用组件的onSave()方法。

src/app/app.component.html
content_copy<button (click)"onSave()"</button>

目标事件

圆括号中的名称—— 比如(click)—— 标记出目标事件。在下面例子中,目标是按钮的 click 事件。

src/app/app.component.html
content_copy有些人更喜欢带on-前缀的备选形式,称之为规范形式:

src/app/app.component.html
content_copy<button on-click>On Save元素事件可能是更常见的目标,但 Angular 会先看这个名字是否能匹配上已知指令的事件属性,就像下面这个例子:

src/app/app.component.html
content_copy<!-- `myClick` is an event on the custom `ClickDirective` --> <div (myClick)"clickMessage=$event" clickable>click with myClick 
  

更多关于该myClick指令的解释,见给输入/输出属性起别名

如果这个名字没能匹配到元素事件或已知指令的输出属性,Angular 就会报“未知指令”错误。

$event和事件处理语句

在事件绑定中,Angular 会为目标事件设置事件处理器。

当事件发生时,这个处理器会执行模板语句。 典型的模板语句通常涉及到响应事件执行动作的接收器,例如从 HTML 控件中取得值,并存入模型。

绑定会通过名叫$event的事件对象传递关于此事件的信息(包括数据值)。

事件对象的形态取决于目标事件。如果目标事件是原生 DOM 元素事件,$event就是DOM事件对象,它有像targettarget.value这样的属性。

考虑这个范例:

src/app/app.component.html
content_copy<input [value]"currentHero.name" (input)"currentHero.name=$event.target.value" >

上面的代码在把输入框的value属性绑定到firstName属性。 要监听对值的修改,代码绑定到输入框的input事件。 当用户造成更改时,input事件被触发,并在包含了 DOM 事件对象 ($event) 的上下文中执行这条语句。

要更新firstName属性,就要通过路径$event.target.value来获取更改后的值。

如果事件属于指令(回想一下,组件是指令的一种),那么$event具体是什么由指令决定。

使用EventEmitter实现自定义事件

通常,指令使用 AngularEventEmitter来触发自定义事件。 指令创建一个EventEmitter实例,并且把它作为属性暴露出来。 指令调用EventEmitter.emit(payload)来触发事件,可以传入任何东西作为消息载荷。 父指令通过绑定到这个属性来监听事件,并通过$event对象来访问载荷。

假设HeroDetailComponent用于显示英雄的信息,并响应用户的动作。 虽然HeroDetailComponent包含删除按钮,但它自己并不知道该如何删除这个英雄。 最好的做法是触发事件来报告“删除用户”的请求。

下面的代码节选自HeroDetailComponent

src/app/hero-detail.component.ts (template)
content_copytemplate: ` <div> <img src="{{heroImageUrl}}"> <span [style.text-decoration]="lineThrough"> {{prefix}} {{hero?.name}} </span> <button (click)="delete()">Delete</button> </div>`
src/app/hero-detail.component.ts (deleteRequest)
content_copy// This component makes a request but it can't actually delete a hero. deleteRequest = new EventEmitter<Hero>(); delete() { this.deleteRequest.emit(.hero); }

组件定义了deleteRequest属性,它是EventEmitter实例。 当用户点击删除时,组件会调用delete()方法,让EventEmitter发出一个Hero对象。

现在,假设有个宿主的父组件,它绑定了HeroDetailComponentdeleteRequest事件。

src/app/app.component.html (event-binding-to-component)
content_copy<app-hero-detail (deleteRequest)"deleteHero($event)" [hero]"currentHero"></app-hero-detail>

deleteRequest事件触发时,Angular 调用父组件的deleteHero方法, 在$event变量中传入要删除的英雄(来自HeroDetail)。

模板语句有副作用

deleteHero方法有副作用:它删除了一个英雄。 模板语句的副作用不仅没问题,反而正是所期望的。

ThedeleteHeromethod has a side effect: it deletes a hero. Template statement side effects are not just OK,but expected.

删除这个英雄会更新模型,还可能触发其它修改,包括向远端服务器的查询和保存。 这些变更通过系统进行扩散,并最终显示到当前以及其它视图中。


双向数据绑定 ([(...)])

我们经常需要显示数据属性,并在用户作出更改时更新该属性。

在元素层面上,既要设置元素属性,又要监听元素事件变化。

Angular 为此提供一种特殊的双向数据绑定语法:[(x)][(x)]语法结合了属性绑定的方括号[x]事件绑定的圆括号(x)

[( )] = 盒子里的香蕉

想象盒子里的香蕉来记住方括号套圆括号。

当一个元素拥有可以设置的属性x和对应的事件xChange时,解释[(x)]语法就容易多了。 下面的SizerComponent符合这个模式。它有size属性和伴随的sizeChange事件:

src/app/sizer.component.ts
content_copy
  1. import { Component, EventEmitter Input Output} from '@angular/core';
  2. @Component({
  3. selector:'app-sizer'`
  4. <div>
  5. <button (click)="dec()" title="smaller">-</button>
  6. <button (click)="inc()" title="bigger">+</button>
  7. <label [style.font-size.px]="size">FontSize: {{size}}px</label>
  8. </div>`
  9. })
  10. exportclass SizerComponent{
  11. @Input() size number |string;
  12. @Output sizeChange =new EventEmitter<number>();
  13. dec.resize(-1);}
  14. inc(+}
  15. resize(delta number){
  16. size Mathmin(40max8++ delta));
  17. sizeChangeemitsize);
  18. }
  19. }

size的初始值是一个输入值,来自属性绑定。(译注:注意size前面的@Input) 点击按钮,在最小/最大值范围限制内增加或者减少size。 然后用调整后的size触发sizeChange事件。

下面的例子中,AppComponent.fontSize被双向绑定到SizerComponent

src/app/app.component.html (two-way-1)
content_copy<app-sizer [(size)]"fontSizePx"></app-sizer> px]>Resizable TextSizerComponent.size初始值是AppComponent.fontSizePx。 点击按钮时,通过双向绑定更新AppComponent.fontSizePx。 被修改的AppComponent.fontSizePx通过样式绑定,改变文本的显示大小。

双向绑定语法实际上是属性绑定和事件绑定的语法糖。 Angular将SizerComponent的绑定分解成这样:

src/app/app.component.html (two-way-2)
content_copy<app-sizer [size]"fontSizePx" (sizeChange)"fontSizePx=$event"></app-sizer>

$event变量包含了SizerComponent.sizeChange事件的荷载。 当用户点击按钮时,Angular 将$event赋值给AppComponent.fontSizePx

显然,比起单独绑定属性和事件,双向数据绑定语法显得非常方便。

我们希望能在像<input><select>这样的 HTML 元素上使用双向数据绑定。 可惜,原生 HTML 元素不遵循x值和xChange事件的模式。

幸运的是,Angular 以NgModel指令为桥梁,允许在表单元素上使用双向数据绑定。


内置指令

上一版本的 Angular 中包含了超过 70 个内置指令。 社区贡献了更多,这还没算为内部应用而创建的无数私有指令。

在新版的 Angular 中不需要那么多指令。 使用更强大、更富有表现力的 Angular 绑定系统,其实可以达到同样的效果。 如果能用简单的绑定达到目的,为什么还要创建指令来处理点击事件呢?

src/app/app.component.html
content_copy我们仍然可以从简化复杂任务的指令中获益。 Angular 发布时仍然带有内置指令,只是没那么多了。 我们仍会写自己的指令,只是没那么多了。

下面来看一下那些最常用的内置指令。它们可分为属性型指令结构型指令


内置属性型指令

属性型指令会监听和修改其它HTML元素或组件的行为、元素属性(Attribute)、DOM属性(Property)。 它们通常会作为HTML属性的名称而应用在元素上。

更多的细节参见属性型指令一章。 很多Angular模块,比如RouterModuleFormsModule都定义了自己的属性型指令。 本节将会介绍几个最常用的属性型指令:

  • NgClass- 添加或移除一组CSS类

  • NgStyle- 添加或移除一组CSS样式

  • NgModel- 双向绑定到HTML表单元素


NgClass 指令

我们经常用动态添加或删除 CSS 类的方式来控制元素如何显示。 通过绑定到NgClass,可以同时添加或移除多个类。

CSS 类绑定是添加或删除单个类的最佳途径。

src/app/app.component.html
content_copy当想要同时添加或移除多个CSS 类时,NgClass指令可能是更好的选择。

试试把ngClass绑定到一个 key:value 形式的控制对象。这个对象中的每个 key 都是一个 CSS 类名,如果它的 value 是true,这个类就会被加上,否则就会被移除。

组件方法setCurrentClasses可以把组件的属性currentClasses设置为一个对象,它将会根据三个其它组件的状态为truefalse而添加或移除三个类。

src/app/app.component.ts
content_copycurrentClasses: {}; setCurrentClasses{ // CSS classes: added/removed per current state of component properties .currentClasses = { 'saveable': .canSave 'modified'!.isUnchanged'special'.isSpecial }; NgClass属性绑定到currentClasses,根据它来设置此元素的CSS类:

src/app/app.component.html
content_copy<div [ngClass]"currentClasses">This div is initially saveable,unchanged,and special 
  

你既可以在初始化时调用setCurrentClassess(),也可以在所依赖的属性变化时调用。


NgStyle 指令

我们可以根据组件的状态动态设置内联样式。NgStyle绑定可以同时设置多个内联样式。

样式绑定是设置单一样式值的简单方式。

src/app/app.component.html
content_copyfont-size]"isSpecial ? 'x-large' : 'smaller'" > This div is x-large or smaller. 如果要同时设置多个内联样式,NgStyle指令可能是更好的选择。

NgStyle需要绑定到一个 key:value 控制对象。 对象的每个 key 是样式名,它的 value 是能用于这个样式的任何值。

来看看组件的setCurrentStyles方法,它会根据另外三个属性的状态把组件的currentStyles属性设置为一个定义了三个样式的对象:

src/app/app.component.ts
content_copycurrentStyles{}; setCurrentStyles// CSS styles: set per current state of component properties .currentStyles 'font-style'.canSave ? 'italic' 'normal''font-weight'.isUnchanged 'bold' 'font-size''24px' '12px' NgStyle属性绑定到currentStyles,以据此设置此元素的样式:

src/app/app.component.html
content_copy<div [ngStyle]"currentStyles"> This div is initially italic,normal weight,and extra large (24px). setCurrentStyles(),也可以在所依赖的属性变化时调用。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


ANGULAR.JS:NG-SELECTANDNG-OPTIONSPS:其实看英文文档比看中文文档更容易理解,前提是你的英语基础还可以。英文文档对于知识点讲述简明扼要,通俗易懂,而有些中文文档读起来特别费力,基础差、底子薄的有可能一会就会被绕晕了,最起码英文文档中的代码与中文文档中的代码是一致的,但知识点讲述实在是差距太大。Angular.jshasapowerfuldire
AngularJS中使用Chart.js制折线图与饼图实例  Chart.js 是一个令人印象深刻的 JavaScript 图表库,建立在 HTML5 Canvas 基础上。目前,它支持6种图表类型(折线图,条形图,雷达图,饼图,柱状图和极地区域区)。而且,这是一个独立的包,不依赖第三方 JavaScript 库,小于 5KB。   其中用到的软件:   Chart.js框架,版本1.0.2,一
IE浏览器兼容性后续前言 继续尝试解决IE浏览器兼容性问题,结局方案为更换jquery、angularjs、IE的版本。 1.首先尝试更换jquery版本为1.7.2 jquery-1.9.1.js-->jquery-1.7.2.js--> jquery2.1.4.js 无效 2.尝试更换IE版本IE8 IE11-
Angular实现下拉菜单多选写这篇文章时,引用文章地址如下:http://ngmodules.org/modules/angularjs-dropdown-multiselecthttp://dotansimha.github.io/angularjs-dropdown-multiselect/#/AngularJSDropdownMultiselectThisdire
在AngularJS应用中集成科大讯飞语音输入功能前言 根据项目需求,需要在首页搜索框中添加语音输入功能,考虑到科大讯飞语音业务的强大能力,遂决定使用科大讯飞语音输入第三方服务。软件首页截图如下所示: 涉及的源代码如下所示: //语音识别$rootScope.startRecognize = function() {var speech;
Angular数据更新不及时问题探讨前言 在修复控制角标正确变化过程中,发觉前端代码组织层次出现了严重问题。传递和共享数据时自己使用的是rootScope,为此造成了全局变量空间的污染。根据《AngularJs深度剖析与最佳实践》,如果两个控制器的协作存在大量的数据共享和交互可以利用Factory等服务的“单例”特性为它们注入一个共享对象来传递数据。而自己在使用rootScope
HTML:让表单、文本框只读,不可编辑的方法有时候,我们希望表单中的文本框是只读的,让用户不能修改其中的信息,如使中国">的内容,"中国"两个字不可以修改。实现的方式归纳一下,有如下几种。方法1:onfocus=this.blur()中国"onfocus=this.blur()>方法2:readonly中国"readonly>中国"readonly="tru
在AngularJS应用中实现微信认证授权遇到的坑前言 项目开发过程中,移动端新近增加了一个功能“微信授权登录”,由于自己不是负责移动端开发的,但最后他人负责的部分未达到预期效果。不能准确实现微信授权登录。最后还得靠自己做进一步的优化工作,谁让自己是负责人呢?原来负责人就是负责最后把所有的BUG解决掉。 首先,熟悉一下微信授权部分的源代码,如下所示:
AngularJS实现二维码信息的集成思路需求 实现生成的二维码包含订单详情信息。思路获取的内容数据如下: 现在可以获取到第一级数据,第二级数据data获取不到。利用第一级数据的获取方法获取不到第二级数据。for(i in data){alert(i); //获得属性 if(typeof(data[i]) == "o
Cookie'data'possiblynotsetoroverflowedbecauseitwastoolarge(5287>4096bytes)!故事起源 项目开发过程中遇到以上问题,刚开始以为只是个警告,没太在意。后来发现直接影响到了程序的执行效果。果断寻找解决方法。问题分析 根据Chrome浏览器信息定位,显示以下代码存在错误:
AngularJS控制器controller之间如何通信angular控制器通信的方式有三种:1,利用作用域继承的方式。即子控制器继承父控制器中的内容2,基于事件的方式。即$on,$emit,$boardcast这三种方式3,服务方式。写一个服务的单例然后通过注入来使用利用作用域的继承方式由于作用域的继承是基于js的原型继承方式,所以这里分为两种情况,当作用域上面的值
AngularJS路由问题解决遇到了一个棘手的问题:点击优惠详情时总是跳转到药店详情页面中去。再加一层地址解决了,但是后来发现问题还是来了:Couldnotresolve'yhDtlMaintain/yhdetail'fromstate'yhMaintain'药店详情http://192.168.1.118:8088/lmapp/index.html#/0优惠券详情
书海拾贝之特殊的ng-src和ng-href在说明这两个指令的特殊之前,需要先了解一下ng的启动及执行过程,如下:1)浏览器加载静态HTML文件并解析为DOM;2)浏览器加载angular.js文件;3)angular监听DOMContentLoaded事件,监听到时开始启动;4)angular寻找ng-app指令,确定作用范围;
angularjs实现页面跳转并进行参数传递Angular页面传参有多种办法,我在此列举4种最常见的:1.基于ui-router的页面跳转传参(1)在AngularJS的app.js中用ui-router定义路由,比如现在有两个页面,一个页面(producers.html)放置了多个producers,点击其中一个目标,页面跳转到对应的producer页,同时将producerId
AngularJS实现表格数据的编辑,更新和删除效果实现首先,我们先建立一些数据,当然你可以从你任何地方读出你的数据var app = angular.module('plunker', ['ui.bootstrap']);app.controller('MainCtrl', function($scope) { $scope.name = 'World'; $sc
ANGULAR三宗罪之版本陷阱      坑!碰到个大坑,前面由于绑定日期时将angular版本换为angular-1.3.0-beta.1时,后来午睡后,登录系统,发现无论如何都登陆不进去了,经过调试,发现数据视图已经无法实现双向绑定了。自己还以为又碰到了“僵尸程序”了呢,对比药店端的程序发现并没有什么不同之处。后来自己经过一番思索才隐约感觉到是不是angular的版本造成的,将版本换为之前
JS实现分页操作前言 项目开发过程中,进行查询操作时有可能会检索出大量的满足条件的查询结果。在一页中显示全部查询结果会降低用户的体验感,故需要实现分页显示效果。受前面“JS实现时间选择插件”的启发,自己首先需要查看一下HTML5能否实现此效果。 整了半天,不管是用纯CSS3也好,还是用tmpagination.js还是bootstrap组件也好,到最后自己静下心来理
浏览器兼容性解决之道前言 浏览器兼容性一直是前端开发中不得不面对的一个问题。而最突出的就是IE。对绝大多数公司来说,兼容IE6的性价比已经很低,而IE7则几乎已经绝迹。所以,常见的兼容性下限是IE8。这也正是Angular1.2x的兼容性目标,Angular团队声明:Angular的持续集成服务器会在IE8下运行所有的测试。但这些测试不会运行在IE7及以下版本,它们也不会保证An
JS利用正则表达式校验手机号绪 由于项目需求,需要在前端实现手机号码的校验。当然了,对于基本的格式校验应该放在客户端进行,而不需要再将待校验的手机号发送至服务端,在服务端完成校验,然后将校验结果返回给客户端,客户端根据返回的结果再进行进一步的处理。如此反而复杂化了处理过程。 其实,处于安全考虑,应该在服务端进行二次校验。以下为在客户端的JS中校验手机号码格式
基于项目实例解析ng启动加载过程前言 在AngularJS项目开发过程中,自己将遇到的问题进行了整理。回过头来总结一下angular的启动过程。 下面以实际项目为例进行简要讲解。1.载入ng库2.等待,直到DOM树构造完毕。3.发现ng-app,自动进入启动引导阶段。4.根据ng-app名称找到相应的路由。5.加载默认地址。6.Js顺序执行,加载相应模版页sys_tpls/