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 ? '已评分' : '评&nbsp;&nbsp;分'; 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项目积累总结】优秀组件以及应用实例的更多相关文章

  1. 【angular5项目积累总结】avatar组件

    View Code import { Component, HostListener, ElementRef } from '@angular/core'; import { Adal4Service ...

  2. 【angular5项目积累总结】breadcrumb面包屑组件

    view code <div class="fxs-breadcrumb-wrapper" aria-label="Navigation history" ...

  3. 【angular5项目积累总结】panel组件

    view code panel.component.css :host { display:flex; min-width:300px } panel.component.html <heade ...

  4. 【angular5项目积累总结】遇到的一些问题以及解决办法

    1.项目中字符串特别是\r\n,替换成br之后,在页面换行无法生效? 答:绑定元素 innerHTML. <div class="panel-body" [innerHTML ...

  5. 【angular5项目积累总结】消息订阅服务

    code import { Injectable } from '@angular/core'; import { Subject } from 'rxjs/Subject'; @Injectable ...

  6. 【angular5项目积累总结】文件上传

    <div class="form-group row"> <label class="col-sm-2 col-form-label"> ...

  7. 【angular5 项目积累总结】项目公共样式

    main.css @font-face { font-family: 'wf_segoe-ui_normal'; src: local('Segoe UI'),url('../fonts/segoe- ...

  8. 【angular5项目积累总结】侧栏菜单 navmenu

    View Code import { Component, OnInit } from '@angular/core'; import { HttpClient } from '@angular/co ...

  9. 【angular5项目积累总结】结合adal4实现http拦截器(token)

    import { Injectable } from '@angular/core'; import { HttpEvent, HttpInterceptor, HttpHandler, HttpRe ...

随机推荐

  1. 关于mysql中[Err] 1451 -Cannot delete or update a parent row: a foreign key constraint fails

    mysql> SET FOREIGN_KEY_CHECKS = 0; Query OK, 0 rows affected (0.02 sec)   mysql> delete from r ...

  2. GO学习笔记 - 用defer来实现try{}finally{}

    在Delphi中,try{}finally{}语句非常有用,对于一定要最终执行的语句,我们放到finally,从而保证程序顺利执行!在GO语言中没有try{}finally{}语句,但是GO语言用另外 ...

  3. Gogland编译Syncthing!

    说明:我仅仅以这个Syncthing工程为例,来说明如何正确使用Goland编译其他人写的工程,应该具有普遍意义,看懂这篇博客,你想用Gogland去编译其他人的工程,应该不是问题!! Syncthi ...

  4. Eclipse导出JAR过程

    Eclipse是一款免费的JAVA开发环境,被各个软件公司使用,可以说是目前使用最多的JAVA开发工具了,网址:http://www.eclipse.org 下面演示如何建立JAVA工程和导出JAR: ...

  5. “全栈2019”Java异常第二十一章:finally不被执行的情况

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java异 ...

  6. grunt 常用插件

    grunt-contrib-uglify:代码压缩 grunt-contrib-jshint:检查js拼写错误 csslint:检查css语法错误

  7. windows文件名太长无法删除的解决办法

    安装nodejs 的模块hexo后,由于香重新安装,在删除的时候却提示文件名太长无法删除,dos命令.回收站各种都无法搞定,后来找到解决办法: 1.进入这些文件的所在目录的上层目录,右键这些文件的所在 ...

  8. 根据现有PDF模板填充信息(SpringBoot)

    根据现有PDF模板填充信息(SpringBoot+maven) 首先得有一个pdf模板,建立pdf模板需要下载工具 红色框为文本框,filename为域名.java需要根据域名赋值 pom 文件配置 ...

  9. 无比迅速敏捷地开发iOS超精美控件

    目录 前言 设计 编码 PaintCode 前言 自从人生第一篇博客<iOS中的预编译指令的初步探究>问世以来 浏览量竟然达到了360多,(路过的大神勿笑!)这些浏览量使我兴奋异常但又令我 ...

  10. Echarts【1、数据过多导致显示不全分页,2、数据展示探讨分析】

    var len=<c:out value="${len }"></c:out>; var dataZoom_end=null; //为空默认100%所以默认 ...