mp-2

http拦截器,参考:
官网:https://angular.cn/guide/http#intercepting-requests-and-responses
设置header:https://blog.csdn.net/wanglui1990/article/details/78796662
https://www.cnblogs.com/changyaoself/p/8539048.html
https://www.cnblogs.com/leejay6567/p/9462758.html
https://juejin.im/post/5b59c89de51d45190a4336d8#comment
https://www.jianshu.com/p/165c0b6d1475

Angular 2 AsyncPipe,参考:
https://segmentfault.com/a/1190000008759314

创建拦截器的service:
ng g service share/http-interceptor

在share.module中:

providers:[
  {
    provide:HTTP_INTERCEPTORS,
    useClass:HttpInterceptorService, // HttpInterceptorService自己服务的名字,其他都是固定的。
    multi:true
  }
]

service:

import '../utils/base64.js';
declare var Base64: any;

const baseurl = '';

@Injectable({
  providedIn: 'root'
})
export class HttpInterceptorService implements HttpInterceptor {

  constructor(private nzMessageService: NzMessageService,) {
  }
  
  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    console.log("req:",req);
    console.log("req-params:",req.params);
    
    // 处理request的参数:可以什么都不做;或者增加header里面的token。
    req = req.clone({
      url: `${baseurl}${req.url}`,
      params: req.params.delete('__isNeedHeader'),
      body: req.body instanceof Object ? this.deleteOwnProperty(req.body, '__isNeedHeader') : null,
    })
    
    // 回调函数:
    return next.handle(req)
      .pipe(
        retry(2), /*失败时重试2次,可自由设置(共执行n+1次)*/
        tap(res=>{ // 任意执行,打印res查看数据
          console.log("tap:",res);
        }),
        filter(res => res instanceof HttpResponse), // 过滤HttpResponse,还会有一个其他的格式,没有用的,eg:{type: 0}
        map((res: HttpResponse<any>) => this.handleSuccess(res)), // 没有发生异常,就执行success
        // catchError(this.handleError.bind(this)),
        catchError(error=>this.handleError(error)) // 接口发生异常了,那么走错误的方法
      )
  }
  
  // 成功
  handleSuccess(res:HttpResponse<any>):HttpEvent<any> {
    const resHeaders =res.headers; // 头
    console.log("resHeaders:",resHeaders);
    const status_code = resHeaders.get('status_code')|| resHeaders.get('Status_code'); // 头status
    const total =resHeaders.get('x-total-count')||resHeaders.get('x-Total-Count'); // 头 tatal
    const data= res.body; // res.body
    console.log("total:",total);
    
    if(status_code==='200'||!status_code){ // 真正的成功(我们用headers里面的status,200或者不存在是成功)
      if(!!total){
        console.log("total:",total);
        return res.clone({
          body:{data:res.body,total:total},
          // body:{data,total}
        });
      }else{
        return res;
      }
    }else { // 错误:headers里面有加密的错误信息
      console.log("Base64:",Base64);
      const base64= new Base64();
      let status_msg = resHeaders.get('status_msg')||resHeaders.get('Status_msg')||'服务器异常';
      status_msg = base64.decode(status_msg); // 错误的写法,汉字无法解析的。
      /*去掉了前后的双引号*/
      if(status_msg[0]==='"'){
        status_msg= status_msg.slice(1,status_msg.length); // 默认第二个参数不传
      }
      if(status_msg[status_msg.length-1]=='"'){
        status_msg= status_msg.slice(0,status_msg.length-1); // 第二个参数传-1即可。
      }
      throw new HttpErrorResponse({ // 重新抛出一个http的错误异常(模拟500情况的数据结构)。
        error:null,
        headers:res.headers,
        status:parseInt(status_code),
        statusText:status_msg,
        url:res.url,
      })
    }
    console.log("成功res:",res);
    // return res; // 最开始什么都没有的时候,必须需要一个返回。
  }


  // 失败:404,500,
  handleError(error){
    console.log("失败error:",error);
    console.log("error里面的error-evnet:",error.error instanceof ErrorEvent);
    if(error.error instanceof ErrorEvent){ // 
      console.log('error-if');
      console.error('An error occurred:', error.error.message);
      return throwError((error.error.message));
    }else{ // 404,500,
      console.log('error-else');
      let status_msg = error.statusText||'服务器异常';
      if(!!error&&error.status===1000){
        // goToLogin:跳转到登录页
        // this.authService.goToLoginPage(); // this.router.navigate(['/pages/login']);
        return;
      }
      if(!!error&&error.status===404){
        status_msg= '请求的接口不存在';
      }
      // 500的时候,没有取到明确的 错误信息(头部的错误信息)
      this.nzMessageService.error(status_msg);
      return throwError(status_msg); // 在浏览器中抛出一个异常
    }
  }

  // 删除对象的属性:
  private deleteOwnProperty(obj: Object, field: string) {
    if (obj.hasOwnProperty(field)) {
      delete obj[field];
    }
    return obj;
  }
}

注:我觉得没有使用baseService好,因为错误的时候,并没有取到错误信息,且传参不舒服。

// 500时候的错误返回:
HttpErrorResponse {headers: HttpHeaders, status: 500, statusText: "Internal Server Error", url: "http://xxx.xxxx.com:4200/marketplace-web/api/product/get-productAll/aa?page=1&size=5", ok: false,}
	error: null
	headers: HttpHeaders {normalizedNames: Map(0), lazyUpdate: null, lazyInit: ƒ}
	message: "Http failure response for http://xxx.xxx.com:4200/marketplace-web/api/product/get-productAll/aa?page=1&size=5: 500 Internal Server Error"
	name: "HttpErrorResponse"
	ok: false
	status: 500
	statusText: "Internal Server Error"
	url: "http://xxx.xxx.com:4200/marketplace-web/api/product/get-productAll/aa?page=1&size=5"
// get请求拼接参数
 return this.http.get(url, {params: {page: '1', size: '5'}})

树结构每次都调用,确实太浪费了,所以使用service-BehaviorSubject:

 ng g service core/category-tree


ng g c product/category-subtree
ng g c product/product-list-filter

问题小结:

  • 输入属性发生变化,如何监听???
    1.get和set
    2.生命周期钩子函数
    3.订阅啊

  • Set的时候,如果add和delete后,值会变化么?是不是跟对象一样,是引用类型?

  • ChangeDetectorRef和changeDetection: ChangeDetectionStrategy.OnPush,

开始home页面:

ng g c home/product-list
ng g c home/product-categories
ng g c home/publish-section
ng g c home/product-list-item

详情页面:

ng g c product/product-head


// 获取用户评论
public commentData:{total:number,data:[],iscomment:number}={
  total:0,data:[],iscomment:2,
}



flex布局的时候:
ul>li,li里面是文字:

注:
1.ul要flex-wrap换行
2.li要不缩,shrink:0;

input属性的时候,使用了get方法。

按钮的防重复点击:(跟搜索一样的)

public collectEmit$ = new Subject();

// 初始化这个
this.collectEmit$
  .pipe(
    debounceTime(300),
    tap(res=>{
      console.log("tap的res:",res);
    }),
    distinctUntilChanged(),
  ).subscribe(res=>{
    this.collect.emit(res);
})



// 调用函数:
this.collectEmit$.next(data);


注:因为有distinctUntilChanged,所以只有值变化后才可以触发事件。data改变属性也是可以监听到的。

rxjs-finalize:
描述:Call a function when observable completes or errors。
成功和失败都会执行 的函数。

购买一系列操作还没做!

轮播和用户评价:

ng g c product/product-screenshot
ng g c product/product-intro
ng g c product/product-other  
ng g c product/user-evaluate // 评价
ng g c product/user-evaluate-list   // 评价列表

set和get的使用:

正常:

@Input() data:any; // 评论列表


ngOnInit() {
  console.log(this.data); //  undefined
  setTimeout(()=>{
    console.log(this.data); // 正确的数据
  },1000)
}

ngAfterViewInit(){
  console.log("ngAfterViewInit:",this.data); // 也是获取不到数的。
}

get和set:

_data:any;

@Input()
set data(value){ // 设置
  console.log("value %C%C",value);
  if(!value) {
    this._data={total:0,data:[]};
  }
  this._data = value;
}

get data(){ // 取值
  return this._data;
}


// 其他值的使用:
get total(){
  // console.log('aaaa');
  return this.data&&this.data.total;
}
get commentList(){
  return this.data&&this.data.data;
}

管道:slice:eg:

 <li *ngFor="let i of collection | slice:1:3">{{i}}</li>
 
collection: string[] = ['a', 'b', 'c', 'd'];

注:看下管道那个,已经忘光了。

报错:eg:

ERROR Error: 
	ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked.
	Previous value: 'ngForOf: [object Object]'. Current value: 'ngForOf: [object Object],[object Object]'.

参考:
https://blog.csdn.net/qq_33242126/article/details/79734150
https://www.cnblogs.com/xudengwei/p/9214959.html
https://blog.csdn.net/friend_ship/article/details/81773057
案例分析:

<li class="mp-user-evaluate-list__item"
    *ngFor="let item of (commentList | slice:0:count)">
</li>


count:any=1;

ngAfterViewInit(){
  console.log("ngAfterViewInit:",this.data);
  this.count=2;
  // Promise.resolve().then(() => this.count = 2);
}

angular的动画:官网:https://angular.cn/guide/animations

angular获取dom元素:
参考:
https://blog.csdn.net/idomyway/article/details/83656366
https://blog.csdn.net/qq_28004379/article/details/80801378

获取元素的样式:

getComputedStyle(elDom, null)

生命周期钩子:
https://www.colabug.com/2645773.html

computedIntroHeight:浏览器大小变化,也会执行的。

文本是输入属性传递进来的,盒子的h在输入属性渲染后才能获取;那么h用什么事件监听?
ngAfterViewChecked,然后用this.cdRef.detectChanges(); (ChangeDetectorRef)强制刷新视图。

注:这个用法不太好,因为只要窗口大小有变化,就会执行;那么其他的操作,eg:NzNotificationService,弹框,也会执行,使用了ngAfterViewChecked的组件会重新渲染,效果有问题的。(鼠标移入NzNotificationService,页面h会变化的)

时间格式化:

npm install date-fns 

1.30.1和2.0.1版本的使用不一样了!
eg:年月日的格式化:

import { format, compareAsc } from 'date-fns'

format(new Date(2014, 1, 11), 'MM/dd/yyyy') // 2.x
format(new Date(2014, 1, 11), 'MM/DD/YYYY') // 1.x

文档:https://date-fns.org/

 ng g service  share/concat

新建模块和组件:文件名与文件夹名不一致:

ng g m carousel/mp-carousel --flat

ng g c carousel/mp-carousel --flat
 npm install hammerjs
 npm i ngx-image-gallery
 

ng-content 内容投影。

ngx-image-gallery:参数:

imageBorderRadius:'20px', // 图片的圆角
imageOffset: '40px', // add gap between image and it's container (default 20px)
showCloseControl: false, // 是否显示关闭按钮
showDeleteControl: false, // 是否显示删除按钮
showExtUrlControl: false,
imagePointer: true,
showImageTitle: true, // 是否显示描述
backdropColor: 'rgba(0, 0, 0, 0.5)', // 背景颜色
showThumbnails: true, // 是否显示缩略图
inline: true, // 弹框模式还是inline模式
showArrows: true, // 是否显示箭头
thumbnailSize:60, // 缩略图的大小。thumbnail:缩略图
reactToMouseWheel:true, // 是否鼠标滚动,好像方向是反着的!!!!
reactToKeyboard:false, // 键盘是否可以切换图片(弹框的时候,才可以使用键盘)

轮播图:

就是antd的轮播图源码!照着看一遍吧。
路径:/node_modules/ng-zorro-antd/fesm2015/ng-zorro-antd.js

引出的问题:
@HostBinding()和@HostListener():参考:
https://www.cnblogs.com/cme-kai/p/8352087.html
https://segmentfault.com/a/1190000008878888
https://blog.csdn.net/ligaoming_123/article/details/81531623

NgTemplateOutlet 参考:

https://segmentfault.com/a/1190000009530554
https://segmentfault.com/a/1190000015944548
ng-template, ng-container and ngTemplateOutlet:参考:
https://blog.csdn.net/m0_37529303/article/details/80690518
[https://blog.csdn.net/Create_mylife/article/details/85615585](https://blog.csdn.net
/Create_mylife/article/details/85615585)
https://www.jianshu.com/p/e5bed2678ab1

个人的博客内容:eg:https://www.cnblogs.com/cme-kai/p/8497146.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的编程语言。它旨在成为一门简单、高效、安全和并发的编程语言,特别适用于构建高性能的服务器和分布式系统。以下是Go语言的一些主要特点和优势: 简洁性:Go语言的语法简单直观,易于学习和使用。它避免了复杂的语法特性,如继承、重载等,转而采用组合和接口来实现代码的复用和扩展。 高性能:Go语言具有出色的性能,可以媲美C和C++。它使用静态类型系统和编译型语言的优势,能够生成高效的机器码。 并发性:Go语言内置了对并发的支持,通过轻量级的goroutine和channel机制,可以轻松实现并发编程。这使得Go语言在构建高性能的服务器和分布式系统时具有天然的优势。 安全性:Go语言具有强大的类型系统和内存管理机制,能够减少运行时错误和内存泄漏等问题。它还支持编译时检查,可以在编译阶段就发现潜在的问题。 标准库:Go语言的标准库非常丰富,包含了大量的实用功能和工具,如网络编程、文件操作、加密解密等。这使得开发者可以更加专注于业务逻辑的实现,而无需花费太多时间在底层功能的实现上。 跨平台:Go语言支持多种操作系统和平台,包括Windows、Linux、macOS等。它使用统一的构建系统(如Go Modules),可以轻松地跨平台编译和运行代码。 开源和社区支持:Go语言是开源的,具有庞大的社区支持和丰富的资源。开发者可以通过社区获取帮助、分享经验和学习资料。 总之,Go语言是一种简单、高效、安全、并发的编程语言,特别适用于构建高性能的服务器和分布式系统。如果你正在寻找一种易于学习和使用的编程语言,并且需要处理大量的并发请求和数据,那么Go语言可能是一个不错的选择。
Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的编程语言。它旨在成为一门简单、高效、安全和并发的编程语言,特别适用于构建高性能的服务器和分布式系统。以下是Go语言的一些主要特点和优势: 简洁性:Go语言的语法简单直观,易于学习和使用。它避免了复杂的语法特性,如继承、重载等,转而采用组合和接口来实现代码的复用和扩展。 高性能:Go语言具有出色的性能,可以媲美C和C++。它使用静态类型系统和编译型语言的优势,能够生成高效的机器码。 并发性:Go语言内置了对并发的支持,通过轻量级的goroutine和channel机制,可以轻松实现并发编程。这使得Go语言在构建高性能的服务器和分布式系统时具有天然的优势。 安全性:Go语言具有强大的类型系统和内存管理机制,能够减少运行时错误和内存泄漏等问题。它还支持编译时检查,可以在编译阶段就发现潜在的问题。 标准库:Go语言的标准库非常丰富,包含了大量的实用功能和工具,如网络编程、文件操作、加密解密等。这使得开发者可以更加专注于业务逻辑的实现,而无需花费太多时间在底层功能的实现上。 跨平台:Go语言支持多种操作系统和平台,包括Windows、Linux、macOS等。它使用统一的构建系统(如Go Modules),可以轻松地跨平台编译和运行代码。 开源和社区支持:Go语言是开源的,具有庞大的社区支持和丰富的资源。开发者可以通过社区获取帮助、分享经验和学习资料。 总之,Go语言是一种简单、高效、安全、并发的编程语言,特别适用于构建高性能的服务器和分布式系统。如果你正在寻找一种易于学习和使用的编程语言,并且需要处理大量的并发请求和数据,那么Go语言可能是一个不错的选择。
Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的编程语言。它旨在成为一门简单、高效、安全和并发的编程语言,特别适用于构建高性能的服务器和分布式系统。以下是Go语言的一些主要特点和优势: 简洁性:Go语言的语法简单直观,易于学习和使用。它避免了复杂的语法特性,如继承、重载等,转而采用组合和接口来实现代码的复用和扩展。 高性能:Go语言具有出色的性能,可以媲美C和C++。它使用静态类型系统和编译型语言的优势,能够生成高效的机器码。 并发性:Go语言内置了对并发的支持,通过轻量级的goroutine和channel机制,可以轻松实现并发编程。这使得Go语言在构建高性能的服务器和分布式系统时具有天然的优势。 安全性:Go语言具有强大的类型系统和内存管理机制,能够减少运行时错误和内存泄漏等问题。它还支持编译时检查,可以在编译阶段就发现潜在的问题。 标准库:Go语言的标准库非常丰富,包含了大量的实用功能和工具,如网络编程、文件操作、加密解密等。这使得开发者可以更加专注于业务逻辑的实现,而无需花费太多时间在底层功能的实现上。 跨平台:Go语言支持多种操作系统和平台,包括Windows、Linux、macOS等。它使用统一的构建系统(如Go Modules),可以轻松地跨平台编译和运行代码。 开源和社区支持:Go语言是开源的,具有庞大的社区支持和丰富的资源。开发者可以通过社区获取帮助、分享经验和学习资料。 总之,Go语言是一种简单、高效、安全、并发的编程语言,特别适用于构建高性能的服务器和分布式系统。如果你正在寻找一种易于学习和使用的编程语言,并且需要处理大量的并发请求和数据,那么Go语言可能是一个不错的选择。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值