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

可输入列表

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

List列表 - 图1

API

List

参数说明类型默认值
[renderHeader]list hederstring | TemplateRef-
[renderFooter]list footerstring | TemplateRef-

ListItem

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

Brief

辅助说明.