1. 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属性
.tab-html thead {
display: table;
table-layout: fixed;
height: 35px;
}
.tab-html thead tr th {
background-color: #e9eef2;
}
.tab-html thead tr td:nth-last-of-type(1) {
box-sizing: border-box;
border: 0;
}
.tab-html tbody {
display: block;
height: 161px;
padding-right: 35px;
}
.tab-html .tbody {
overflow-y: scroll;
overflow-x: hidden;
/*滚动条样式*/
&::-webkit-scrollbar {
width: 5px;
/*height: 4px;*/
}
&::-webkit-scrollbar-thumb {
border-radius: 10px;
-webkit-box-shadow: inset 0 0 3px rgba(0, 0, 0, 0.2);
background: rgba(0, 0, 0, 0.2);
}
&::-webkit-scrollbar-track {
-webkit-box-shadow: inset 0 0 3px rgba(0, 0, 0, 0.2);
border-radius: 0;
background: rgba(0, 0, 0, 0.1);
}
}
.tab-html tbody tr {
display: table;
width: 100%;
table-layout: fixed;
}
// html
<table cellspacing="0" cellpadding="0" [border]="1" class="tab-html">
<thead
[style.width]="
editRowTable.length > 5 ? 'calc(100% - 5px)' : '100%'
"
>
<tr>
<th>序号</th>
<th>不良现象</th>
<th>描述</th>
<th>位置</th>
<th>是否维修</th>
<th style="visibility: hidden; width: 35px"></th>
</tr>
</thead>
<tbody
[class]="
editRowTable.length > 5 ? 'tbody editorhtml' : 'editorhtml'
"
(scroll)="scroll($event)"
>
<tr
[class]="i === mouseenterIndex ? 'tr' : ''"
*ngFor="let item of editRowTable; let i = index"
(mouseover)="trMouseover(i)"
(mouseout)="trMouseout()"
(click)="trClick(item, i)"
(dblclick)="trdbclick(i)"
>
<td>{{ item.a }}</td>
<td>{{ item.bmName }}</td>
<td>{{ item.bmDescribe }}</td>
<td>{{ item.location }}</td>
<td style="position: relative">
<lq-icon
[iName]="
item.defactResult ? 'lq-seleted' : 'lq-reduce-fill'
"
style="color: green"
class="iconsize"
></lq-icon>
<div
[class]="i === mouseenterIndex ? 'visi2' : 'visi'"
style="
width: 14px;
height: calc(100% + 2px);
justify-content: center;
align-items: center;
position: absolute;
top: -1px;
right: -17px;
background-color: #ffffff;
"
>
<lq-icon
class="iconsize"
style="color: red"
iName="lq-reduce-fill"
(click)="tdIconClick(item, i)"
></lq-icon>
</div>
</td>
</tr>
</tbody>
</table>
// 表格增加滚动条锁定最后
ngAfterViewChecked(): void {
// if (this.flag) {
// const editorhtml = this.el.nativeElement.querySelector('.editorhtml');
// editorhtml.scrollTop = editorhtml.scrollHeight - editorhtml.clientHeight;
// this.flag = false;
// }
}
// 滚动不刷新滚动条位置
// scroll(e) {
// this.flag = false;
// }
6. 原生上传图片
.inp_span {
width: 100%;
height: 100%;
display: inline-block;
position: absolute;
left: 0;
bottom: -6px;
}
.span_div {
width: 140px;
height: 50px;
position: absolute;
left: 50%;
margin-left: -70px;
}
.icon {
display: block;
height: 30px;
position: absolute;
top: -3px;
left: 50%;
margin-left: -15px;
font-size: 30px;
::ng-deep .anticon {
position: absolute;
}
}
.span_icon {
display: block;
width: 20px;
height: 20px;
position: absolute;
top: 2px;
left: 100%;
margin-left: 5px;
font-size: 20px;
cursor: pointer;
::ng-deep .anticon {
position: absolute;
left: 0;
}
}
.span_div:hover > .icon {
color: red;
}
.lab {
width: 140px;
height: 50px;
position: absolute;
left: 50%;
bottom: 0;
margin-left: -70px;
box-sizing: border-box;
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
}
.span_div:hover > .lab {
color: red;
}
.file_span {
display: flex;
width: 200%;
height: 20px;
line-height: 20px;
position: absolute;
left: -50%;
top: 50%;
margin-top: -10px;
justify-content: center;
align-items: center;
}
.span_div:hover > .sdb_icon {
::ng-deep .ng-star-inserted {
color: red;
}
}
// html
<div style="user-select: none">图片路径</div>
<div lq-row [lqGutter]="20">
<div lq-col [lqSpan]="24">
<div
style="
width: 100%;
min-height: 72px;
border: 1px dashed #ddd;
border-radius: 4px;
font-size: 15px;
color: #b7bdc0;
text-align: center;
line-height: 83px;
position: relative;
"
>
<span class="inp_span">
<div class="span_div">
<lq-icon
*ngIf="fileList.length === 0"
iName="lq-upload"
class="icon"
></lq-icon>
<label *ngIf="fileList.length === 0" for="file" class="lab"
>点击上传图片</label
>
<span *ngIf="fileList.length !== 0" class="file_span"
><span style="position: relative">
{{ this.fileList[0].name }}
<lq-icon
iName="lq-ashbin"
class="span_icon"
(click)="icon_click()"
></lq-icon>
</span>
</span>
</div>
<input
style="visibility: hidden"
id="file"
type="file"
name="file"
multiple="multiple"
accept="image/jpeg,image/jpg,image/png"
(change)="fileOnChange($event)"
/>
</span>
</div>
</div>
</div>
// 上传图片
async fileOnChange(e) {
this.fileInput = e.target;
const files = e.target.files[0]; // 上传数据流
const val = e.target.value; // 路径
if (e.target.files && files) {
if (files.size > 1024 * 1024 * 3) {
this.fileInput = {};
this.util.Toast('图片大小不能大于3M!', 'warning');
return false;
}
}
const reader = new FileReader();
reader.readAsDataURL(e.target.files[0]);
reader.onload = ((files) => { //fils-元素标签, 这里是将图片转成base64格式
return (e) => {
this.filePath = e.target.result; // base64文件流
};
})(files);
this.fileList = [...files];
// 如果value和title不同时清掉选同一个会选不上,已经存在了
this.fileInput.value = '';
this.fileInput.title = '';
console.log(this.fileInput, 'this.fileInput');
}
// icon_click
icon_click() {
this.filePath = '';
this.fileInput = {};
this.fileList = [];
}
7. ChangeDetectorRef ChangeDetectionStrategy
7.1 ChangeDetectorRef :
angular 会在我们的组件发生变化的时候,对我们的组件执行变化检测,如果检测到我们的数据发生了变化,就会执行某些操作,如修改绑定数据的时候更新视图。这样一来,当我们的组件数据比较多的时候,angular就会有很多操作在静悄悄地进行,因此,就需要ChangeDetectorRef来实时检测数据的变化并更新视图数据
import { ChangeDetectorRef, Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
/**
*markForCheck() - 当输入已更改或视图中发生了事件时,组件通常会标记为脏的(需要重新渲染)。调用此方法会确保即使那些触发器没有被触发,也仍然检查该组件。<br>在组件的 metadata 中如果设置了 changeDetection: ChangeDetectionStrategy.OnPush 条件,那么变化检测不会再次执行,除非手动调用该方法。
*detach() - 从变化检测树中分离变化检测器,该组件的变化检测器将不再执行变化检测,除非手动调用 reattach() 方法。
*reattach() - 重新添加已分离的变化检测器,使得该组件及其子组件都能执行变化检测
*detectChanges() - 从该组件到各个子组件执行一次变化检测 检查该视图及其子视图。与 <a href="https://angular.cn/api/core/ChangeDetectorRef#detach">detach</a> 结合使用可以实现局部变更检测。
*checkNoChanges() - 检查变更检测器及其子检测器,如果检测到任何更改,则抛出异常。
*/
constructor(
private navMenuTabService: NavMenuTabService,
private cd: ChangeDetectorRef // 注册
private changeDetection:ChangeDetectionStrategy.OnPush // 只需要加入在这里就可以
) { }
async TabSelectedClick() {
await this.selectedIndexChange.emit(this.selectedIndex);
this.cd.detectChanges(); // 实时检测页面及其子元素的变化
}
onPush()策略时 浅拷贝数据触发输入属性的变化以触发检查
7.2 ChangeDetectionStrategy
默认变更检测器用来检测更改的策略。设置后,将在下次触发变更检测时生效。
子组件的属性的变化由输入属性决定,那么这个时候就可以启用OnPush这种变更检测策略,这样输入属性不变的时候就不用检测了.
8. HttpClient
<span
*ngIf="this.Item.FileName && Item.DisposeReuslt === '特批'"
class="inp_span"
>
<lq-icon iName="lq-attachent"></lq-icon>
<span>{{ this.Item.FileName }}</span>
<lq-icon
iName="lq-upload"
style="color: red; margin-left: 6px"
(click)="exClick()"
></lq-icon>
</span>
import { HttpClient } from '@angular/common/http';
constructor(
private http: HttpClient // 用http请求接口
) { }
async exClick() {
this.http.post(this.apiConfigure.rootUrl + '/WMS/odata/OqcMains/DowOqcFile', {
fileName: this.Item.FileName,
fileUrl: this.Item.FilePath
}, { responseType: 'blob' }).subscribe(res => {
this.downloadFile(res, this.Item.FileName);
});
}
downloadFile(data: Blob, fileName: string) {
const blob = new Blob([data]);
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = fileName;
a.click();
window.URL.revokeObjectURL(url);
}
9. 发布订阅模式
unSub() {
return this.subject.unsubscribe();
}
使用此模式销毁,在谷歌浏览器报错,需要引入rxjs的Subscription
subscription = new Subscription();