【angular5项目积累总结】优秀组件以及应用实例
1.手机端 图片预览组件
组件:sideshow
效果图:(预览图全屏 且可以左右移动)

code:
<div class="row ui-app-screenshot">
<img src="{{proUrl(pic.Url)}}" *ngFor="let pic of currApp.Pictures;let i = index;" (click)="onViewPicture(i)">
</div>
<slideshow [imageUrls]="slideUrls" [showArrows]="false" #slideRef (click)="onCloseViewPicture()"></slideshow>
import { ViewChild, Component, ElementRef, Renderer2 } from '@angular/core';
import { Router, ActivatedRoute, Params } from '@angular/router';
import { AppStoreService } from '../../service/appService';
import { ConfigureOptions } from '../../configure/configure.options';
import { BrowserService } from '../../service/browser.service';
import { Adal4Service } from '../../adal/adal4.service';
@Component({
selector: 'mobile-app-info',
templateUrl: './mobileAppInfo.html',
styleUrls: ['./mobileAppInfo.css']
})
export class MobileAppInfo {
@ViewChild('slideRef') slideRef: ElementRef;
constructor(
private router: Router,
private actRouter: ActivatedRoute,
private appService: AppStoreService,
private browserService: BrowserService,
private appOptions: ConfigureOptions,
private renderer: Renderer2,
private adalService: Adal4Service) {
}
id: string;
platSource: any;
showRateBox: boolean = false;
rateVal: number = 0;
screenHeight: any;
currApp: any = [];
currPackage: any = [];
userRateStars: any = [{}, {}, {}, {}, {}];
slideUrls: any = [{}];
eleSlidershow: any;
username: string;
ngOnInit(): void {
this.initWinHeight();
this.eleSlidershow = this.slideRef && this.slideRef['container'].nativeElement;
if (this.eleSlidershow) {
this.renderer.setStyle(this.eleSlidershow, 'position', 'fixed');
this.renderer.setStyle(this.eleSlidershow, 'top', '0');
this.renderer.setStyle(this.eleSlidershow, 'z-index', '1041');
this.renderer.setStyle(this.eleSlidershow, 'display', 'none');
}
this.actRouter.params.subscribe((params: Params) => {
this.id = params["id"];
this.platSource = this.browserService.getBrowserInfo();
if (!this.platSource.isMobile && !this.platSource.isWechat) {
this.router.navigate(["/appInfo/" + this.id], {});
}
this.appService.GetAppInfo(this.id, (rtv) => {
this.initAppData(rtv);
});
});
this.username = this.adalService.userInfo.username || "未登录";
}
initAppData(rtv: any) {
this.currApp.IconUrl = this.proUrl(rtv.IconUrl);
this.currApp.Name = rtv.Name || '';
this.currApp.DownloadCount = rtv.DownloadCount || 0;
this.currApp.AvgScore = rtv.AvgScore || 0;
this.currApp.ScoreCount = rtv.ScoreCount || 0;
this.currApp.Pictures = rtv.Pictures || [];
this.currApp.CreatedOn = rtv.CreatedOn || '';
this.currApp.Category = rtv.Category || '';
this.currApp.Version = rtv.Version || '';
this.currApp.IsScored = rtv.IsScored || false;
this.currApp.Description = this.proTxt(rtv.Description);
this.currApp.scoreTxt = rtv.IsScored ? '已评分' : '评 分';
this.slideUrls = rtv.Pictures.map(p => this.proUrl(p.Url));
if (this.slideUrls.length == 0) {
this.slideUrls.push({});
}
this.slideRef['slideIndex'] = this.slideUrls.length - 1;
let _pkgArray = this.platSource.platform.Android ? rtv.AndoridPackages[0] : rtv.iOSPackages[0];
this.currPackage.Version = _pkgArray && _pkgArray.Version || '';
this.currPackage.ReleaseNotes = this.proTxt(_pkgArray && _pkgArray.ReleaseNotes);
this.currPackage.FileSize = this.proSize(_pkgArray && _pkgArray.FileSize || 0);
}
initWinHeight() {
this.screenHeight = (window.screen.height || window.innerHeight) - 52;
let self = this;
window.addEventListener("resize", function () {
self.screenHeight = (window.screen.height || window.innerHeight) - 52;
});
}
proUrl(url) {
return this.appOptions.BlobUrl + url;
}
proDevice() {
let devStr = '';
if (this.platSource.platform.Android) {
this.currPackage ? devStr = 'Android' : devStr = '不支持Android';
} else if (this.platSource.platform.iPad || this.platSource.platform.iPhone) {
this.currPackage ? devStr = 'IOS' : devStr = '不支持IOS';
}
return devStr;
}
proTxt(txt: string) {
return txt ? txt.replace(/\r?\n/g, "<br />").replace('undefined', '<font color="#a1a1a1">暂无信息</font>') : '<font color="#a1a1a1">暂无信息</font>';
}
proSize(limit: any) {
var size = "";
if (!limit) return size;
if (limit < 0.1 * 1024) { //如果小于0.1KB转化成B
size = limit.toFixed(2) + "B";
} else if (limit < 0.1 * 1024 * 1024) {//如果小于0.1MB转化成KB
size = (limit / 1024).toFixed(2) + "KB";
} else if (limit < 0.1 * 1024 * 1024 * 1024) { //如果小于0.1GB转化成MB
size = (limit / (1024 * 1024)).toFixed(2) + "MB";
} else { //其他转化成GB
size = (limit / (1024 * 1024 * 1024)).toFixed(2) + "GB";
}
var sizestr = size + "";
var len = sizestr.indexOf("\.");
var dec = sizestr.substr(len + 1, 2);
if (dec == "00") {//当小数点后为00时 去掉小数部分
return sizestr.substring(0, len) + sizestr.substr(len + 3, 2);
}
return sizestr;
}
getStarClass(val: number): number {
return Math.floor(val * 2) || 0;
}
onOpenRate() {
if (this.checkAuth()) {
this.showRateBox = true;
this.rateVal = 0;
}
}
onCloseRate() {
this.showRateBox = false;
}
onSetScore() {
this.appService.SetScore(this.id, this.rateVal, (rtv) => {
this.currApp.IsScored = true;
this.onCloseRate()
});
}
onRate(value): void {
this.rateVal = value;
}
getDownloadUrl(): void {
if (!this.checkAuth()) {
return;
}
this.appService.GetDownloadUrl(this.id, this.platSource.platform.Android ? "Android" : "iOS", (ret) => {
if (!!ret) {
window.location.href = ret;
} else {
alert("获取下载地址失败,请稍后再试");
}
});
}
private checkAuth(): boolean {
var user = this.adalService.userInfo;
if (user.authenticated) {
return true;
}
localStorage.setItem("app-store-redirect-uri", window.location.pathname);
this.router.navigate(["/login"], {});
return false;
}
onViewPicture(index: any): void {
this.renderer.setStyle(this.eleSlidershow, 'display', 'block');
this.slideRef && this.slideRef['onButtonClick'].call(this.slideRef, index || 0);
}
onCloseViewPicture(): void {
this.renderer.setStyle(this.eleSlidershow, 'display', 'none');
}
}
2.树形组件或者树形下拉框组件
ng2tree ngx-treeview
地址:https://github.com/leovo2708/ngx-treeview
angular2-tree
2.1 难点:ng2tree 异步加载
预览:

code:
<tree [tree] ="orgTree" [settings]="{rootIsVisible: false}" (nodeSelected)="logEvent($event)" (nodeMoved)="onNodeMoved($event)"></tree>
import { Component } from '@angular/core';
import { Router, ActivatedRoute, Params } from '@angular/router';
import { TreeModel, NodeEvent, TreeModelSettings } from 'ng2-tree';
import { UserService } from '../common/userService';
import { CommonService } from '../../providers/commonService';
@Component({
selector: 'orgTree',
templateUrl: './orgTree.html',
styleUrls: ['./orgTree.css']
})
export class orgTree {
menuItems: any = [
{ title: "添加", icon: "#FxSymbol0-0bd", event: this.onAdd.bind(this) },
{ title: "编辑", icon: "#FxSymbol0-0bf", event: this.onEdit.bind(this) }
]
public orgTree: TreeModel;
public nodeTree: Array<TreeModel> = [];
constructor(
private router: Router,
private actRouter: ActivatedRoute,
private comService: CommonService,
private userService: UserService) {
this.onRefresh(comService);
}
loadNodes(id: string,callback:any):void {
let rtv: Array<TreeModel> = [];
this.userService.LoadSyncTree(id, (result) => {
let length: number = result.children.length;
if (length > 0) {
for (let i = 0; i < length; i++) {
let node: TreeModel =
{
id: result.children[i].id,
value: result.children[i].value,
loadChildren: (cb) => {this.loadNodes(result.children[i].id,cb)
}
}
rtv.push(node);
}
}
callback(rtv);
});
}
currGroup: string = '';
groupId: string = '';
ngOnInit(): void {
this.actRouter.params.subscribe((params: Params) => {
this.groupId = params["id"];
if (!this.groupId) {
this.groupId = "org";
}
this.currGroup = params["id"];
this.onLoadTree(this.groupId);
});
}
public logEvent(e: NodeEvent): void {
if (e.node.id.toString() == '') {
alert('根机构不可编辑!')
} else {
this.currGroup = e.node.id.toString();
if (this.currGroup != "") {
this.router.navigate(['/ou/org/' + this.currGroup + '/member'], {});
}
}
}
onLoadTree(id: string) {
this.userService.LoadSyncTree(null, (result) => {
const treeSettings: TreeModelSettings = {
static: false,
rightMenu: false,
leftMenu: false,
isCollapsedOnInit: false
}
let length: number = result.children.length;
for (let i = 0; i < length; i++) {
result.children[i].loadChildren = (callback) => {this.loadNodes(result.children[i].id,callback)
}
};
this.orgTree = result;
this.orgTree.settings = treeSettings;
});
}
onEdit() {
if (this.currGroup == '' || this.currGroup == null) {
alert('请先选择一个机构再进行编辑操作。');
}
else
this.router.navigate(['/ou/' + this.groupId + '/' + this.currGroup + '/edit'], {});
}
onAdd() {
if (this.currGroup == '' || this.currGroup == null) {
alert('请先选择一个机构再进行添加操作。');
} else
this.router.navigate(['/ou/' + this.groupId + '/' + this.currGroup + '/create'], {});
}
onOUFresh() {
this.userService.RefreshTree(this.groupId, (result) => {
const treeSettings: TreeModelSettings = {
static: false,
rightMenu: false,
leftMenu: false,
isCollapsedOnInit: false
}
this.orgTree = result;
this.orgTree.settings = treeSettings;
});
}
onClose() {
this.router.navigate(['/ou']);
}
onRefresh(comService: CommonService) {
this.comService.notifyObservable$.subscribe(data => {
if (data == 'refreshOrgTree') {
this.currGroup = '';
this.onLoadTree(this.groupId);
}
}, error => {
console.log(`subscribe error:${error}`)
})
}
onNodeMoved(e: NodeEvent): void {
console.log("curr:" + e.node.parent.value);
console.log(e.node.value);
}
}
2.2 改造:下拉框 tree
预览:

3. 上传组件
组件:ng2-file-upload
code:
<input type="file" ng2FileSelect [uploader]="uploader" [(ngModel)]="fileInfo"/>
import { Component } from '@angular/core';
import { Router, ActivatedRoute, Params } from '@angular/router';
import { FileUploader, FileItem, ParsedResponseHeaders } from 'ng2-file-upload';
import { Adal4Service } from '../../adal/adal4.service';
import { ConfigureService } from '../../configure/configure.service';
import { UserService } from '../common/userService';
@Component({
selector: 'usersimport',
templateUrl: './importUsers.html',
styleUrls: ['./importUsers.css']
})
export class importUsers {
errorMsg: string;
lstHistory: any;
template: string;
token: string;
uploader: FileUploader = null;
parentUrl: string;
fileInfo: string;
groupId: string;
orgPath: string;
menuItems: any = [
{ title: "刷新", icon: "#FxSymbol0-0bf", event: this.onRefresh.bind(this) }
]
constructor(
private router: Router,
private actRouter: ActivatedRoute,
public configService: ConfigureService,
private adal4Service: Adal4Service,
private userService: UserService
) {
this.template = "/api/import/template?type=user";
this.token = this.adal4Service.userInfo.token;
this.uploader = new FileUploader({
url: "/api/Import/User",
method: "POST",
itemAlias: "dataFile",
autoUpload: false,
headers: [{ name: 'Authorization', value: `Bearer ${this.token}` }]
});
this.menuItems = [
{ title: "上传", icon: "#FxSymbol0-001", event: this.uploadExcel.bind(this) },
{ title: "刷新", icon: "#FxSymbol0-0bf", event: this.onRefresh.bind(this) }
];
this.onRefresh();
}
onRefresh(): void {
this.userService.RefreshHistory("ImportUser", (rtv) => {
this.lstHistory = rtv;
});
}
ngOnInit(): void {
this.parentUrl = this.router.url;
this.actRouter.params.subscribe((params: Params) => {
this.groupId = params["groupId"] || this.groupId;
this.groupId && this.initOrgPath();
});
}
onClose() {
this.router.navigate(['/ou/org/' + this.groupId + '/member/'], {});
}
uploadExcel() {
if (this.uploader != null && this.uploader.queue[0] != null) {
this.uploader.queue[0].onSuccess = (response, status, headers) => {
if (status == 200) {
this.errorMsg = "";
let rtv = JSON.parse(response);
if (rtv.RetCode == 0) {
this.errorMsg = "文件上传成功,结果查看结果列表。";
} else {
this.errorMsg = "文件上传失败." + rtv.RetMessage;
}
} else {
this.errorMsg = response;
}
this.fileInfo = "";
};
this.uploader.onBeforeUploadItem = (item) => {
item.withCredentials = false;
}
this.uploader.onSuccessItem = this.onSuccessItem.bind(this);
this.uploader.onErrorItem = this.onErrorItem.bind(this);
this.uploader.uploadAll();
}
else {
alert('请选择上传文件!');
}
}
onErrorItem(item: FileItem, response: string, status: number, headers: ParsedResponseHeaders): any {
if (status != 200) {
alert('导入人员失败!');
} else {
alert(response);
}
this.fileInfo = "";
this.onClose();
}
onSuccessItem(item: FileItem, response: string, status: number, headers: ParsedResponseHeaders): any {
if (status == 200) {
this.errorMsg = "";
let rtv = JSON.parse(response);
if (rtv.status == 1) {
alert('文件上传成功!');
} else {
alert('文件上传失败,错误信息:' + rtv.message);
}
this.fileInfo = "";
this.uploader.removeFromQueue(item);
this.uploader.clearQueue();
this.uploader.destroy();
this.onRefresh();
} else {
alert(response);
}
this.onClose();
}
initOrgPath() {
let _array = decodeURIComponent(this.groupId).split(',');
if (_array && _array.length > 0) {
this.orgPath = _array.map(o => o.replace('OU=', '')).reverse().join('#');
if(this.orgPath) this.orgPath = decodeURIComponent(this.orgPath);
}
}
}
2.头像上传 编辑图片组件
angular2-img-cropper
3.日期选择
https://github.com/CuppaLabs/angular2-datetimepicker
4.列表分页组件
npm install ngx-pagination
5.html 编辑器
npm install angular-froala-wysiwyg --save
https://summernote.org/
https://github.com/lula/ngx-summernote/
推荐组件库:
FreeNG
https://freengs.github.io/#/main/introduction
http://www.wheelsfactory.cn
https://www.jqwidgets.com/angular/#demos/angular2/angular-fileupload-defaultfunctionality.htm
https://www.telerik.com/kendo-angular-ui/components/
https://www.infragistics.com/angularsite/components/grids_and_lists.html
https://docs.nativescript.org/angular/ui/ng-ui-widgets/date-picker
https://material.angular.io/components/datepicker/examples
https://js.devexpress.com/Demos/WidgetsGallery/Demo/DataGrid/RecordPaging/jQuery/Light/
https://akveo.github.io/ngx-admin/?utm_source=github&utm_medium=ngx_admin_readme&utm_campaign=themes
未完待续,本文章待补充....
【angular5项目积累总结】优秀组件以及应用实例的更多相关文章
- 【angular5项目积累总结】avatar组件
View Code import { Component, HostListener, ElementRef } from '@angular/core'; import { Adal4Service ...
- 【angular5项目积累总结】breadcrumb面包屑组件
view code <div class="fxs-breadcrumb-wrapper" aria-label="Navigation history" ...
- 【angular5项目积累总结】panel组件
view code panel.component.css :host { display:flex; min-width:300px } panel.component.html <heade ...
- 【angular5项目积累总结】遇到的一些问题以及解决办法
1.项目中字符串特别是\r\n,替换成br之后,在页面换行无法生效? 答:绑定元素 innerHTML. <div class="panel-body" [innerHTML ...
- 【angular5项目积累总结】消息订阅服务
code import { Injectable } from '@angular/core'; import { Subject } from 'rxjs/Subject'; @Injectable ...
- 【angular5项目积累总结】文件上传
<div class="form-group row"> <label class="col-sm-2 col-form-label"> ...
- 【angular5 项目积累总结】项目公共样式
main.css @font-face { font-family: 'wf_segoe-ui_normal'; src: local('Segoe UI'),url('../fonts/segoe- ...
- 【angular5项目积累总结】侧栏菜单 navmenu
View Code import { Component, OnInit } from '@angular/core'; import { HttpClient } from '@angular/co ...
- 【angular5项目积累总结】结合adal4实现http拦截器(token)
import { Injectable } from '@angular/core'; import { HttpEvent, HttpInterceptor, HttpHandler, HttpRe ...
随机推荐
- C#中字段、属性、只读、构造函数赋值、反射赋值的相关
C#中字段.属性和构造函数赋值的问题 提出问题 首先提出几个问题: 1.如何实现自己的注入框架? 2.字段和自动属性的区别是什么? 3.字段和自动属性声明时的直接赋值和构造函数赋值有什么区别? 4.为 ...
- ASP.NET MVC学习目录
一.ASP.NET MVC原理详解 1.了解MVC架构模式 3.学习ASP.NET MVC的必备语言知识 4.MVC中的razor语法详解 5.ASP.NET MVC路由系统机制详细讲解 6.ASP. ...
- Sql语法高级应用之一:使用sql语句如何实现不同的角色看到不同的数据
前言 在常见的管理系统中,通常都有这样的需求,管理员可以看到所有数据,部门可以看到本部门的数据,组长可以看到自己组的数据,组员只能看到自己相关的数据. 一般人的做法是,根据不同的角色通过if...el ...
- Kubernetes 集群安装部署
etcd集群配置 master节点配置 1.安装kubernetes etcd [root@k8s ~]# yum -y install kubernetes-master etcd 2.配置 etc ...
- django系列8.5--使用装饰器(视图函数中)实现用户登录状态检验
views.py def session_auth(fn): def inner(request,*args,**kwargs): status = request.session.get('sess ...
- Java50道经典习题-程序12 计算奖金
题目:企业发放的奖金根据利润提成.利润(I)低于或等于10万元时,奖金可提10%: 利润高于10万元,低于20万元时,低于10万元的部分按10%提成,高于10万元的部分,可提成7.5%: ...
- 【文文殿下】后缀自动机(Suffix Automaton,SAM)学习笔记
前言 后缀自动机是一个强大的数据结构,能够解决很多字符串相关的(String-related)问题. 例如:他可以查询一个字符串在另一个字符串中出现的所有子串,以及查询一个字符串中本质不同的字符串的个 ...
- mysql 主从错误以及监控
同步中的常见的错误和处理 1.现象:在从库上面show slave status\G;出现下列情况, Slave_IO_Running: Yes Slave_S ...
- windows文件名太长无法删除的解决办法
安装nodejs 的模块hexo后,由于香重新安装,在删除的时候却提示文件名太长无法删除,dos命令.回收站各种都无法搞定,后来找到解决办法: 1.进入这些文件的所在目录的上层目录,右键这些文件的所在 ...
- (二)Python 装饰器
1. 函数 在 Python 中,使用关键字 def 和一个函数名以及一个可选的参数列表来定义函数.函数使用 return 关键字来返回值.定义和使用一个最简单的函数例子: >>> ...