1.产品目录结构树:
(1).category-provider.ts:调接口取出目录树结构数据:
/**
* 使用后端拼装好的tree结构数据
*/
public getCategoryTreeData(): Observable<any> {
return new Observable(observable$ => {
this.httpRequest.getRequest(this.api_categoryTrees, {}, {}).subscribe(res => {
if (_.isObject(res)) {
if (res['status'] === 0) {
const newData = [];
newData.push(res['data']);
observable$.next(newData);
} else {
this.notice.error(res['message']);
observable$.next([]);
}
}
}, err => {
observable$.error(err);
});
});
}
(2).查询后端目录列表,由前端拼装为tree结构
/**
* 查询后端目录列表,由前端拼装为tree结构
*/
public getCategoryListData(): Observable<any> {
return new Observable(observable$ => {
this.httpRequest.getRequest(this.api_AllList, {}, {}).subscribe(res => {
if (_.isObject(res)) {
if (res['status'] === 0) {
const result = this.handleJsonTree(res['data']);
const newData = [];
const getNzTree = function (data) {
const childrens = [];
for (let i = 0; i < data.length; i++) {
const treeNode = {
title: data[i].categoryName,
key: data[i].id,
categoryStatus: data[i].categoryStatus,
children: [],
isLeaf: false
};
if (data[i].children && data[i].children.length > 0) {
treeNode.children = getNzTree(data[i].children);
} else {
treeNode.isLeaf = true;
}
childrens.push(treeNode);
}
return childrens;
};
if (result.length > 0) {
const treeNodes = getNzTree(result);
treeNodes[0].expanded = true;
observable$.next(treeNodes);
} else {
observable$.next([]);
}
} else {
this.notice.error(res['message']);
observable$.next([]);
}
}
}, err => {
observable$.error(err);
});
});
}
(3).根据id的长度判断等级,4位1级:
private handleJsonTree(results) {
const tempArr = [];
let minLevelNum = [];
// 根据id的长度判断等级,4位1级
results.forEach(item => {
item['levelNum'] = _.toString(_.get(item, 'id', '')).length / 4; // id先转换成字符串,再取字符串长度进行运算
tempArr.push(item);
minLevelNum.push(item['levelNum']);
});
minLevelNum = _.uniq(minLevelNum);
const minLevel = _.min(minLevelNum);
const _results = tempArr.filter(tItem => tItem.levelNum === minLevel);
let treeDatas = [];
_results.forEach(item => {
treeDatas = this.getJsonTree(results, item.parentId);
});
return treeDatas;
}
先用toString方法将id转换成字符串,再取其长度进行运算。
(4).在组件中调用树:
/**
* 初始化目录结构数据
*/
getCategoryTreeData() {
this.categoryProvider.getCategoryTreeData().subscribe(data => {
if (data.length > 0) {
data[0].expanded = true;
this.nodes = data;
}
this.isSpinning = false;
}, err => {
this.isSpinning = false;
});
}
/**
* 节点单击click事件
* @param data
*/
activeNode(data: NzFormatEmitEvent): void {
data.node.isSelected = true;
this.activedNode = data.node;
this.searchData(true);
}
/* 监听窗体变化 */
ngAfterViewInit() {
this.globalProvider.onWindoResize().subscribe(e => {
if (e) {
this.contentHeight = window.innerHeight - 300 + 'px';
this.treeHeight = window.innerHeight - 230 + 'px';
}
});
}
2.页面上*ngIf=""进行条件判断:
<div nz-row>
<div nz-col [nzSpan]="24" *ngIf="productStatus === '2'">
<nz-form-item nzFlex>
<nz-form-label nz-col [nzRequired]="!isReadOnly" [nzSpan]="2" nzFor="remarks">审核拒绝理由</nz-form-label>
<nz-form-control nz-col [nzSpan]="22">
<input nz-input formControlName="remarks" readonly="readonly">
</nz-form-control>
</nz-form-item>
</div>
</div>
用*ngIf=""控制remarks字段是否显示,这时productStatus字段是Validateform中的字段,*ngIf=""只能判断export中直接声明的字段,若要判断Validateform中的字段,则需要在初始化表单的方法中把这个字段赋值给外部声明的字段:productStatus = '';
/**
* 初始化form
* @param data
*/
initFormData(data) {
this.categoryId = data.categoryId;
this.initFormDataList();
this.validateForm.controls['id'].setValue(data.id);
this.validateForm.controls['categoryId'].setValue(data.categoryId);
this.validateForm.controls['productStatus'].setValue(data.productStatus);
this.productStatus = data.productStatus; // 把表单内部的字段值赋给外部的变量
this.validateForm.controls['remarks'].setValue(data.remarks);
this.categoryProvider.getDataById(this.categoryId).subscribe(data => {
this.validateForm.controls['categoryName'].setValue(data.categoryName); // 根据所属目录Id查目录名
});
this.validateForm.controls['productName'].setValue(data.productName);
......
3.常用的正则表达式:
"^\d+$" //非负整数(正整数 + 0)
"^[0-9]*[1-9][0-9]*$" //正整数
"^((-\d+)|(0+))$" //非正整数(负整数 + 0)
"^-[0-9]*[1-9][0-9]*$" //负整数
"^-?\d+$" //整数
"^\d+(\.\d+)?$" //非负浮点数(正浮点数 + 0)
"^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$" //正浮点数
"^((-\d+(\.\d+)?)|(0+(\.0+)?))$" //非正浮点数(负浮点数 + 0)
"^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$" //负浮点数
"^(-?\d+)(\.\d+)?$" //浮点数
"^[A-Za-z]+$" //由26个英文字母组成的字符串
"^[A-Z]+$" //由26个英文字母的大写组成的字符串
"^[a-z]+$" //由26个英文字母的小写组成的字符串
"^[A-Za-z0-9]+$" //由数字和26个英文字母组成的字符串
"^\w+$" //由数字、26个英文字母或者下划线组成的字符串
"^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$" //email地址
"^[a-zA-z]+://(\w+(-\w+)*)(\.(\w+(-\w+)*))*(\?\S*)?$" //url
/^(d{2}|d{4})-((0([1-9]{1}))|(1[1|2]))-(([0-2]([1-9]{1}))|(3[0|1]))$/ // 年-月-日
/^((0([1-9]{1}))|(1[1|2]))/(([0-2]([1-9]{1}))|(3[0|1]))/(d{2}|d{4})$/ // 月/日/年
"^([w-.]+)@(([[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.)|(([w-]+.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(]?)$" //Emil
"(d+-)?(d{4}-?d{7}|d{3}-?d{8}|^d{7,8})(-d+)?" //电话号码
"^(d{1,2}|1dd|2[0-4]d|25[0-5]).(d{1,2}|1dd|2[0-4]d|25[0-5]).(d{1,2}|1dd|2[0-4]d|25[0-5]).(d{1,2}|1dd|2[0-4]d|25[0-5])$" //IP地址
YYYY-MM-DD基本上把闰年和2月等的情况都考虑进去了 :
^((((1[6-9]|[2-9]\d)\d{2})-(0?[13578]|1[02])-(0?[1-9]|[12]\d|3[01]))|(((1[6-9]|[2-9]\d)\d{2})-(0?[13456789]|1[012])-(0?[1-9]|[12]\d|30))|(((1[6-9]|[2-9]\d)\d{2})-0?2-(0?[1-9]|1\d|2[0-8]))|(((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-0?2-29-))$
4.直接从数据字典中取出状态(状态码转文字):
在用到该状态的组件中:
ngOnInit() {
this.searchData();
this.initMerchantStatus(); // 初始化的时候加载状态
}
/**
* 初始化状态下拉框
*/
initMerchantStatus() {
// 数据字典项加载
this.dictCommonProvider.getLovListByNames(['REFUND_STATUS']).subscribe(res => {
if (res.status === 0) {
this.refundStatus = res.datas[0];
this.refundStatus = this.refundStatus.slice('',''); // 截取状态中的第几位到第几位
} else {
this.notice.error(res.message);
}
});
}
export下面定义refundStatus 为一个空数组,用来传入状态码:refundStatus:any = [];
则这时页面上使用:
<div nz-col [nzSpan]="8">
<nz-form-item nzFlex>
<nz-form-label nz-col [nzRequired]="!isReadOnly" [nzSpan]="6" nzFor="refundStatus">订单状态</nz-form-label>
<nz-form-control nz-col [nzSpan]="14">
<nz-select style="width: 100%" formControlName="refundStatus" nzDisabled>
<nz-option *ngFor="let option of refundStatus" [nzLabel]="option.label" [nzValue]="option.value"></nz-option>
</nz-select>
</nz-form-control>
</nz-form-item>
</div>
数据字段中配置该状态:
this.refundStatus= [
{ value: '0', label: '未完成' },
{ value: '1', label: '已完成' },
];
5.常用日期格式(format):
angular中的日期管道:{{ value_expression | date [ : format [ : timezone [ : locale ] ] ] }}
其中value为日期表达式,是一个Date对象、数字(从 UTC 时代以来的毫秒数)或一个 ISO 字符串 ;format是一个
要包含的日期、时间部分的格式,使用预定义选项或自定义格式字符串。format包括:short、medium、long、full、shortDate、mediumDate、longDate、fullDate、shortTime、mediumTime、longTime、fullTime。locale
是一个 string
,用来定义要使用的区域。timezone
用在格式化中。它能理解 UTC/GMT 和美国大陆时区缩写,但对于一般用途则使用时区偏移(比如 '+0430'
)。 如果没有指定,则使用宿主系统中的设定。
可选. 默认值是 'mediumDate'
.
详见:https://angular.cn/api/common/DatePipe
e.g:
{{ dateObj | date }} // output is 'Jun 15, 2015'
{{ dateObj | date:'medium' }} // output is 'Jun 15, 2015, 9:43:11 PM'
{{ dateObj | date:'shortTime' }} // output is '9:43 PM'
{{ dateObj | date:'mmss' }} // output is '43:11'
{{ birthday | date:"MM/dd/yy" }}
管道还可以组合成链式管道:比如日期格式大写:{{ birthday | date: 'fullDate' | uppercase}}
关键点:
管道类实现了 PipeTransform
接口的 transform
方法,该方法接受一个输入值和一些可选参数,并返回转换后的值。当每个输入值被传给 transform
方法时,还会带上另一个参数。transform
方法是管道的基本要素。 PipeTransform 接口
中定义了它,并用它指导各种工具和编译器。 理论上说,它是可选的。Angular 不会管它,而是直接查找并执行 transform
方法。
你必须在 AppModule
的 declarations
数组中包含这个管道!
e.g:自定义管道举例:
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({name: 'exponentialStrength'})
export class ExponentialStrengthPipe implements PipeTransform {
transform(value: number, exponent: string): number {
let exp = parseFloat(exponent);
return Math.pow(value, isNaN(exp) ? 1 : exp);
} }
下面用组件来演示这个管道:
import { Component } from '@angular/core'; 、
@Component({
selector: 'app-power-booster',
template: ` <h2>Power Booster</h2>
<p>Super power boost: {{2 | exponentialStrength: 10}}</p> `
})
export class PowerBoosterComponent { }
得到结果:(2的10次方)1024。
或者直接做成计算器的形式:
import { Component } from '@angular/core';
@Component({
selector: 'app-power-boost-calculator',
template: `
<h2>Power Boost Calculator</h2>
<div>Normal power: <input [(ngModel)]="power"></div>
<div>Boost factor: <input [(ngModel)]="factor"></div>
<p>
Super Hero Power: {{power | exponentialStrength: factor}}
</p>
`
})
export class PowerBoostCalculatorComponent {
power = 5;
factor = 1;
}