List列表

单个连续模块垂直排列,显示当前的内容、状态和可进行的操作。eg:联系人列表。

规则

  • 一般由主要信息、主要操作、次要信息、次要操作组成。
  • 主要信息和主要操作放在列表的左边,次要信息和次要操作放在列表的右边。

代码演示

基本用法

  1. import { Component } from '@angular/core';
  2. @Component({
  3. selector: 'demo-list-basic',
  4. template: `
  5. <List [className]="'my-list'" [renderHeader]=(renderHeader)>
  6. <ListItem [extra]="'extra content'">Title</ListItem>
  7. </List>
  8. <List [className]="'my-list'" [renderHeader]=(renderHeader1)>
  9. <ListItem multipleLine [arrow]="'horizontal'" (onClick)="onClick()">
  10. Title
  11. <Brief>subtitle</Brief>
  12. </ListItem>
  13. <ListItem multipleLine
  14. [arrow]="'horizontal'"
  15. [platform]="'android'"
  16. (onClick)="onClick()"
  17. >
  18. ListItem (Android)
  19. <Brief>There may have water ripple effect of <br/> material if you set the onClick event.</Brief>
  20. </ListItem>
  21. <ListItem [arrow]="'horizontal'"
  22. [thumb]="'https://zos.alipayobjects.com/rmsportal/dNuvNrtqUztHCwM.png'"
  23. multipleLine
  24. (onClick)="onClick()"
  25. >Title
  26. <Brief>subtitle</Brief>
  27. </ListItem>
  28. </List>
  29. <List [className]="'my-list'" [renderHeader]=(renderHeader2)>
  30. <ListItem>Title</ListItem>
  31. <ListItem [arrow]="'horizontal'" (onClick)="onClick()">Title</ListItem>
  32. <ListItem [extra]="'extra content'" [arrow]="'horizontal'" (onClick)="onClick()">Title</ListItem>
  33. <ListItem [extra]="'10:30'" [align]="'top'" [thumb]="'https://zos.alipayobjects.com/rmsportal/dNuvNrtqUztHCwM.png'" multipleLine>
  34. Title
  35. <Brief>subtitle</Brief>
  36. </ListItem>
  37. </List>
  38. <List [className]="'my-list'" [renderHeader]=(renderHeader3)>
  39. <ListItem multipleLine [extra]="'extra content'">
  40. Title
  41. <Brief>subtitle</Brief>
  42. </ListItem>
  43. </List>
  44. <List [renderHeader]=(renderHeader4)>
  45. <ListItem [thumb]="'https://zos.alipayobjects.com/rmsportal/dNuvNrtqUztHCwM.png'"
  46. [arrow]="'horizontal'"
  47. (onClick)="onClick()"
  48. >My wallet
  49. </ListItem>
  50. <ListItem [thumb]="'https://zos.alipayobjects.com/rmsportal/UmbJMbWOejVOpxe.png'"
  51. (onClick)="onClick()"
  52. [arrow]="'horizontal'"
  53. >
  54. My Cost Ratio
  55. </ListItem>
  56. </List>
  57. <List [className]="'my-list'" [renderHeader]=(renderHeader5)>
  58. <ListItem data-seed="logId">Single line,long text will be hidden with ellipsis;</ListItem>
  59. <ListItem wrap>Multiple line,long text will wrap;Long Text Long Text Long Text Long Text Long Text Long Text</ListItem>
  60. <ListItem [extra]="'extra content'" multipleLine [align]="'top'" wrap>
  61. Multiple line and long text will wrap. Long Text Long Text Long Text
  62. </ListItem>
  63. <ListItem [extra]="'no arrow'" [arrow]="'empty'" [className]="'spe'" wrap>
  64. In rare cases, the text of right side will wrap in the single line with long text. long text long text long text
  65. </ListItem>
  66. </List>
  67. <List [className]="'my-list'" [renderHeader]=(renderHeader6)>
  68. <ListItem [disabled]="disabled" [extra]="" (click)="onDisableClick()">Click to disable</ListItem>
  69. <ListItem>
  70. <select>
  71. <option [value]="'1'">Html select element</option>
  72. <option [value]="'2'" disabled>Unable to select</option>
  73. <option [value]="'3'">option 3</option>
  74. </select>
  75. </ListItem>
  76. </List>
  77. `,
  78. styles: [
  79. `
  80. /deep/ .my-list .spe .am-list-extra {
  81. flex-basis: initial;
  82. }
  83. `
  84. ]
  85. })
  86. export class DemoListBasicComponent {
  87. disabled: boolean = false;
  88. renderFooter: Function;
  89. constructor() {}
  90. renderHeader() {
  91. return 'Basic Style';
  92. }
  93. renderHeader1() {
  94. return 'Subtitle';
  95. }
  96. renderHeader2() {
  97. return 'Customized Right Side(Empty Content / Text / Image)';
  98. }
  99. renderHeader3() {
  100. return 'Align Vertical Center';
  101. }
  102. renderHeader4() {
  103. return 'Icon in the left';
  104. }
  105. renderHeader5() {
  106. return 'Text Wrapping';
  107. }
  108. renderHeader6() {
  109. return 'Other';
  110. }
  111. onClick() {
  112. console.log('click');
  113. }
  114. switchCheck(value) {
  115. console.log('switch status:', value);
  116. }
  117. onDisableClick() {
  118. console.log('click', this.disabled);
  119. this.disabled = true;
  120. }
  121. }

可输入列表

  1. import { Component, OnInit } from '@angular/core';
  2. import { FormGroup, Validators, FormControl } from '@angular/forms';
  3. @Component({
  4. selector: 'demo-list-form',
  5. template: `
  6. <form [formGroup]="registerForm">
  7. <List [renderHeader]=(renderHeader) [renderFooter]=(renderFooter)>
  8. <InputItem [placeholder]="'please input account'"
  9. [error]="isError"
  10. [focus]="onFocus"
  11. [value]="formData.username"
  12. [clear]="true" formControlName="username" id="username"
  13. (onErrorClick)="inputErrorClick($event)"
  14. (onChange)="inputChange($event)"
  15. >
  16. Account
  17. </InputItem>
  18. <InputItem id="password"
  19. formControlName="password"
  20. [placeholder]="'please input password'"
  21. [type]="'password'"
  22. [(ngModel)]="formData.password"
  23. [value]="formData.password"
  24. >
  25. Password
  26. </InputItem>
  27. <ListItem [extra]="_switch">Confirm Infomation</ListItem>
  28. <ListItem>
  29. <Range style="padding: 7px"
  30. [defaultValue]=[20,80]
  31. [min]=0
  32. [max]=100
  33. (onAfterChange)="afterChange($event)"
  34. ></Range>
  35. </ListItem>
  36. <ListItem [extra]="_stepper">Number of Subscribers</ListItem>
  37. <ListItem>
  38. <a Button [type]="'primary'"
  39. [size]="'small'"
  40. [inline]="true"
  41. (onClick)="onSubmit()"
  42. >
  43. Submit
  44. </a>
  45. <a Button
  46. style="margin-left: 2.5px;"
  47. [size]="'small'"
  48. [inline]="true"
  49. (onClick)="onReset()"
  50. >
  51. Reset
  52. </a>
  53. </ListItem>
  54. </List>
  55. </form>
  56. <ng-template #_switch>
  57. <Switch class='oneui-mobile' [checked] = "true" (onChange)='switchCheck($event)'></Switch>
  58. </ng-template>
  59. <ng-template #_stepper>
  60. <Stepper [value]="stepper_value"
  61. [min]="1"
  62. [showNumber]="true"
  63. (onChange)="setpperChange($event)"
  64. ></Stepper>
  65. </ng-template>
  66. `,
  67. styles: [
  68. `
  69. /deep/ .my-list .spe .am-list-extra {
  70. flex-basis: initial;
  71. }
  72. `
  73. ]
  74. })
  75. export class DemoListFormComponent implements OnInit {
  76. renderFooter: Function;
  77. registerForm: FormGroup;
  78. stepper_value: number = 20;
  79. isError: boolean = false;
  80. onFocus: object = {
  81. focus: false
  82. };
  83. formErrors: any = {
  84. username: '',
  85. password: ''
  86. };
  87. formData: any = {
  88. username: '',
  89. password: ''
  90. };
  91. validationMessage: any = {
  92. username: {
  93. minlength: 'At least four characters for account',
  94. maxlength: 'At most ten characters for account',
  95. required: 'username requied'
  96. },
  97. password: {}
  98. };
  99. constructor() {}
  100. renderHeader() {
  101. return 'Form Validation';
  102. }
  103. bindRenderFooter() {
  104. return (this.formErrors && this.formErrors['username']) || '';
  105. }
  106. onClick() {
  107. console.log('click');
  108. }
  109. buildForm(): void {
  110. this.registerForm = new FormGroup({
  111. username: new FormControl(this.formData.username, [
  112. Validators.required,
  113. Validators.maxLength(10),
  114. Validators.minLength(5)
  115. ]),
  116. password: new FormControl(this.formData.password, [])
  117. });
  118. this.registerForm.valueChanges.subscribe(data => this.onValueChanged(data));
  119. this.onValueChanged();
  120. }
  121. onValueChanged(data?: any) {
  122. if (!this.registerForm) {
  123. return;
  124. }
  125. const form = this.registerForm;
  126. for (const field in this.formErrors) {
  127. this.formErrors[field] = '';
  128. const control = form.get(field);
  129. if (control && control.dirty && !control.valid) {
  130. const messages = this.validationMessage[field];
  131. for (const key in control.errors) {
  132. this.formErrors[field] += messages[key] + '\n';
  133. }
  134. }
  135. }
  136. }
  137. beforeSubmit() {
  138. const form = this.registerForm;
  139. for (const field in this.formErrors) {
  140. this.formErrors[field] = '';
  141. const control = form.get(field);
  142. if (control && !control.valid) {
  143. const messages = this.validationMessage[field];
  144. for (const key in control.errors) {
  145. this.formErrors[field] += messages[key] + '\n';
  146. if (field === 'username') {
  147. this.onFocus = {
  148. focus: true
  149. };
  150. }
  151. }
  152. return false;
  153. } else {
  154. return true;
  155. }
  156. }
  157. }
  158. switchCheck(value) {
  159. console.log('switch status:', value);
  160. }
  161. onSubmit() {
  162. if (this.beforeSubmit()) {
  163. console.log(this.registerForm.value);
  164. this.onReset();
  165. } else {
  166. alert('Validation failed');
  167. }
  168. }
  169. onReset() {
  170. this.registerForm.reset();
  171. this.formData = {
  172. ...{
  173. username: '',
  174. password: ''
  175. }
  176. };
  177. this.isError = false;
  178. }
  179. afterChange(event) {
  180. console.log(event, 'afterChange');
  181. }
  182. inputErrorClick(e) {
  183. alert('At least four charactors for account');
  184. }
  185. inputChange(e) {
  186. if (e.replace(/\s/g, '').length < 5 && e.replace(/\s/g, '').length > 0) {
  187. this.isError = true;
  188. } else {
  189. this.isError = false;
  190. }
  191. this.formData.username = e;
  192. }
  193. setpperChange($event) {
  194. console.log($event, 'change');
  195. }
  196. ngOnInit() {
  197. this.buildForm();
  198. this.renderFooter = this.bindRenderFooter.bind(this);
  199. }
  200. }

List 列表 - 图1

API

List

属性说明类型默认值
renderHeaderlist hederString/TemplateRef/Function
renderFooterlist footerString/TemplateRef/Function

List.Item

属性说明类型默认值
thumb缩略图(当为 string 类型时作为 img src)String/TemplateRef
extra右边内容String/TemplateRef
arrow箭头方向(右,上,下), 可选horizontal,up,down,empty,如果是empty则存在对应的dom,但是不显示String
align子元素垂直对齐,可选top,middle,bottomStringmiddle
onClick点击事件的回调函数(): void
error报错样式,右侧文字颜色变成橙色Booleanfalse
multipleLine多行Booleanfalse
wrap是否换行,默认情况下,文字超长会被隐藏,Booleanfalse
platform设定组件的平台特有样式, 可选值为 android, ios, 默认为 cross, 即组件会自动检测设备 UA 应用不同平台的样式String'cross'

List.Item.Brief

辅助说明