1. event废弃

event事件废弃,需要调用事件传入$event获取。

2. 光标锁定

@ViewChildren(LqTextboxComponent) Inputs: QueryList;
this.Inputs.toArray()[4].focus();

3. 抽屉按钮

{
text: ‘删除’,
onclick: async (data) => {
const ID = data.id ? data.id : null;
if (!ID) {
return;
}
await this.service.deleteSmtToDip(ID);
this.Search();
},
visble: (data) => data.rqty === ‘已接收’ // 返回true显示
}

4. 匹配ip地址

constisValid = /^((2[0-4]\d|25[0-5]|[01]?\d\d?).){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$/;

5. 原生table属性

  1. .tab-html thead {
  2. display: table;
  3. table-layout: fixed;
  4. height: 35px;
  5. }
  6. .tab-html thead tr th {
  7. background-color: #e9eef2;
  8. }
  9. .tab-html thead tr td:nth-last-of-type(1) {
  10. box-sizing: border-box;
  11. border: 0;
  12. }
  13. .tab-html tbody {
  14. display: block;
  15. height: 161px;
  16. padding-right: 35px;
  17. }
  18. .tab-html .tbody {
  19. overflow-y: scroll;
  20. overflow-x: hidden;
  21. /*滚动条样式*/
  22. &::-webkit-scrollbar {
  23. width: 5px;
  24. /*height: 4px;*/
  25. }
  26. &::-webkit-scrollbar-thumb {
  27. border-radius: 10px;
  28. -webkit-box-shadow: inset 0 0 3px rgba(0, 0, 0, 0.2);
  29. background: rgba(0, 0, 0, 0.2);
  30. }
  31. &::-webkit-scrollbar-track {
  32. -webkit-box-shadow: inset 0 0 3px rgba(0, 0, 0, 0.2);
  33. border-radius: 0;
  34. background: rgba(0, 0, 0, 0.1);
  35. }
  36. }
  37. .tab-html tbody tr {
  38. display: table;
  39. width: 100%;
  40. table-layout: fixed;
  41. }
  42. // html
  43. <table cellspacing="0" cellpadding="0" [border]="1" class="tab-html">
  44. <thead
  45. [style.width]="
  46. editRowTable.length > 5 ? 'calc(100% - 5px)' : '100%'
  47. "
  48. >
  49. <tr>
  50. <th>序号</th>
  51. <th>不良现象</th>
  52. <th>描述</th>
  53. <th>位置</th>
  54. <th>是否维修</th>
  55. <th style="visibility: hidden; width: 35px"></th>
  56. </tr>
  57. </thead>
  58. <tbody
  59. [class]="
  60. editRowTable.length > 5 ? 'tbody editorhtml' : 'editorhtml'
  61. "
  62. (scroll)="scroll($event)"
  63. >
  64. <tr
  65. [class]="i === mouseenterIndex ? 'tr' : ''"
  66. *ngFor="let item of editRowTable; let i = index"
  67. (mouseover)="trMouseover(i)"
  68. (mouseout)="trMouseout()"
  69. (click)="trClick(item, i)"
  70. (dblclick)="trdbclick(i)"
  71. >
  72. <td>{{ item.a }}</td>
  73. <td>{{ item.bmName }}</td>
  74. <td>{{ item.bmDescribe }}</td>
  75. <td>{{ item.location }}</td>
  76. <td style="position: relative">
  77. <lq-icon
  78. [iName]="
  79. item.defactResult ? 'lq-seleted' : 'lq-reduce-fill'
  80. "
  81. style="color: green"
  82. class="iconsize"
  83. ></lq-icon>
  84. <div
  85. [class]="i === mouseenterIndex ? 'visi2' : 'visi'"
  86. style="
  87. width: 14px;
  88. height: calc(100% + 2px);
  89. justify-content: center;
  90. align-items: center;
  91. position: absolute;
  92. top: -1px;
  93. right: -17px;
  94. background-color: #ffffff;
  95. "
  96. >
  97. <lq-icon
  98. class="iconsize"
  99. style="color: red"
  100. iName="lq-reduce-fill"
  101. (click)="tdIconClick(item, i)"
  102. ></lq-icon>
  103. </div>
  104. </td>
  105. </tr>
  106. </tbody>
  107. </table>
  108. // 表格增加滚动条锁定最后
  109. ngAfterViewChecked(): void {
  110. // if (this.flag) {
  111. // const editorhtml = this.el.nativeElement.querySelector('.editorhtml');
  112. // editorhtml.scrollTop = editorhtml.scrollHeight - editorhtml.clientHeight;
  113. // this.flag = false;
  114. // }
  115. }
  116. // 滚动不刷新滚动条位置
  117. // scroll(e) {
  118. // this.flag = false;
  119. // }

6. 原生上传图片

  1. .inp_span {
  2. width: 100%;
  3. height: 100%;
  4. display: inline-block;
  5. position: absolute;
  6. left: 0;
  7. bottom: -6px;
  8. }
  9. .span_div {
  10. width: 140px;
  11. height: 50px;
  12. position: absolute;
  13. left: 50%;
  14. margin-left: -70px;
  15. }
  16. .icon {
  17. display: block;
  18. height: 30px;
  19. position: absolute;
  20. top: -3px;
  21. left: 50%;
  22. margin-left: -15px;
  23. font-size: 30px;
  24. ::ng-deep .anticon {
  25. position: absolute;
  26. }
  27. }
  28. .span_icon {
  29. display: block;
  30. width: 20px;
  31. height: 20px;
  32. position: absolute;
  33. top: 2px;
  34. left: 100%;
  35. margin-left: 5px;
  36. font-size: 20px;
  37. cursor: pointer;
  38. ::ng-deep .anticon {
  39. position: absolute;
  40. left: 0;
  41. }
  42. }
  43. .span_div:hover > .icon {
  44. color: red;
  45. }
  46. .lab {
  47. width: 140px;
  48. height: 50px;
  49. position: absolute;
  50. left: 50%;
  51. bottom: 0;
  52. margin-left: -70px;
  53. box-sizing: border-box;
  54. cursor: pointer;
  55. -webkit-user-select: none;
  56. -moz-user-select: none;
  57. user-select: none;
  58. }
  59. .span_div:hover > .lab {
  60. color: red;
  61. }
  62. .file_span {
  63. display: flex;
  64. width: 200%;
  65. height: 20px;
  66. line-height: 20px;
  67. position: absolute;
  68. left: -50%;
  69. top: 50%;
  70. margin-top: -10px;
  71. justify-content: center;
  72. align-items: center;
  73. }
  74. .span_div:hover > .sdb_icon {
  75. ::ng-deep .ng-star-inserted {
  76. color: red;
  77. }
  78. }
  79. // html
  80. <div style="user-select: none">图片路径</div>
  81. <div lq-row [lqGutter]="20">
  82. <div lq-col [lqSpan]="24">
  83. <div
  84. style="
  85. width: 100%;
  86. min-height: 72px;
  87. border: 1px dashed #ddd;
  88. border-radius: 4px;
  89. font-size: 15px;
  90. color: #b7bdc0;
  91. text-align: center;
  92. line-height: 83px;
  93. position: relative;
  94. "
  95. >
  96. <span class="inp_span">
  97. <div class="span_div">
  98. <lq-icon
  99. *ngIf="fileList.length === 0"
  100. iName="lq-upload"
  101. class="icon"
  102. ></lq-icon>
  103. <label *ngIf="fileList.length === 0" for="file" class="lab"
  104. >点击上传图片</label
  105. >
  106. <span *ngIf="fileList.length !== 0" class="file_span"
  107. ><span style="position: relative">
  108. {{ this.fileList[0].name }}
  109. <lq-icon
  110. iName="lq-ashbin"
  111. class="span_icon"
  112. (click)="icon_click()"
  113. ></lq-icon>
  114. </span>
  115. </span>
  116. </div>
  117. <input
  118. style="visibility: hidden"
  119. id="file"
  120. type="file"
  121. name="file"
  122. multiple="multiple"
  123. accept="image/jpeg,image/jpg,image/png"
  124. (change)="fileOnChange($event)"
  125. />
  126. </span>
  127. </div>
  128. </div>
  129. </div>
  130. // 上传图片
  131. async fileOnChange(e) {
  132. this.fileInput = e.target;
  133. const files = e.target.files[0]; // 上传数据流
  134. const val = e.target.value; // 路径
  135. if (e.target.files && files) {
  136. if (files.size > 1024 * 1024 * 3) {
  137. this.fileInput = {};
  138. this.util.Toast('图片大小不能大于3M!', 'warning');
  139. return false;
  140. }
  141. }
  142. const reader = new FileReader();
  143. reader.readAsDataURL(e.target.files[0]);
  144. reader.onload = ((files) => { //fils-元素标签, 这里是将图片转成base64格式
  145. return (e) => {
  146. this.filePath = e.target.result; // base64文件流
  147. };
  148. })(files);
  149. this.fileList = [...files];
  150. // 如果value和title不同时清掉选同一个会选不上,已经存在了
  151. this.fileInput.value = '';
  152. this.fileInput.title = '';
  153. console.log(this.fileInput, 'this.fileInput');
  154. }
  155. // icon_click
  156. icon_click() {
  157. this.filePath = '';
  158. this.fileInput = {};
  159. this.fileList = [];
  160. }

7. ChangeDetectorRef ChangeDetectionStrategy

7.1 ChangeDetectorRef :

angular 会在我们的组件发生变化的时候,对我们的组件执行变化检测,如果检测到我们的数据发生了变化,就会执行某些操作,如修改绑定数据的时候更新视图。这样一来,当我们的组件数据比较多的时候,angular就会有很多操作在静悄悄地进行,因此,就需要ChangeDetectorRef来实时检测数据的变化并更新视图数据

  1. import { ChangeDetectorRef, Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
  2. /**
  3. *markForCheck() - 当输入已更改或视图中发生了事件时,组件通常会标记为脏的(需要重新渲染)。调用此方法会确保即使那些触发器没有被触发,也仍然检查该组件。<br>在组件的 metadata 中如果设置了 changeDetection: ChangeDetectionStrategy.OnPush 条件,那么变化检测不会再次执行,除非手动调用该方法。
  4. *detach() - 从变化检测树中分离变化检测器,该组件的变化检测器将不再执行变化检测,除非手动调用 reattach() 方法。
  5. *reattach() - 重新添加已分离的变化检测器,使得该组件及其子组件都能执行变化检测
  6. *detectChanges() - 从该组件到各个子组件执行一次变化检测 检查该视图及其子视图。与 <a href="https://angular.cn/api/core/ChangeDetectorRef#detach">detach</a> 结合使用可以实现局部变更检测。
  7. *checkNoChanges() - 检查变更检测器及其子检测器,如果检测到任何更改,则抛出异常。
  8. */
  9. constructor(
  10. private navMenuTabService: NavMenuTabService,
  11. private cd: ChangeDetectorRef // 注册
  12. private changeDetection:ChangeDetectionStrategy.OnPush // 只需要加入在这里就可以
  13. ) { }
  14. async TabSelectedClick() {
  15. await this.selectedIndexChange.emit(this.selectedIndex);
  16. this.cd.detectChanges(); // 实时检测页面及其子元素的变化
  17. }

onPush()策略时 浅拷贝数据触发输入属性的变化以触发检查

7.2 ChangeDetectionStrategy

默认变更检测器用来检测更改的策略。设置后,将在下次触发变更检测时生效。
子组件的属性的变化由输入属性决定,那么这个时候就可以启用OnPush这种变更检测策略,这样输入属性不变的时候就不用检测了.

8. HttpClient

  1. <span
  2. *ngIf="this.Item.FileName && Item.DisposeReuslt === '特批'"
  3. class="inp_span"
  4. >
  5. <lq-icon iName="lq-attachent"></lq-icon>
  6. <span>{{ this.Item.FileName }}</span>
  7. <lq-icon
  8. iName="lq-upload"
  9. style="color: red; margin-left: 6px"
  10. (click)="exClick()"
  11. ></lq-icon>
  12. </span>
  1. import { HttpClient } from '@angular/common/http';
  2. constructor(
  3. private http: HttpClient // 用http请求接口
  4. ) { }
  5. async exClick() {
  6. this.http.post(this.apiConfigure.rootUrl + '/WMS/odata/OqcMains/DowOqcFile', {
  7. fileName: this.Item.FileName,
  8. fileUrl: this.Item.FilePath
  9. }, { responseType: 'blob' }).subscribe(res => {
  10. this.downloadFile(res, this.Item.FileName);
  11. });
  12. }
  13. downloadFile(data: Blob, fileName: string) {
  14. const blob = new Blob([data]);
  15. const url = window.URL.createObjectURL(blob);
  16. const a = document.createElement('a');
  17. a.href = url;
  18. a.download = fileName;
  19. a.click();
  20. window.URL.revokeObjectURL(url);
  21. }

9. 发布订阅模式

  1. unSub() {
  2. return this.subject.unsubscribe();
  3. }
  4. 使用此模式销毁,在谷歌浏览器报错,需要引入rxjsSubscription
  5. subscription = new Subscription();