angular6的table组件开发的实现示例


Posted in Javascript onDecember 26, 2018

背景及吐槽:

今年有机会再次接触angualr这个框架,想起第一次接触ng还是16年读书的时候,当时还是ng1,然后学起来特别辛苦,学习曲线特别陡峭;而今年有一个项目重构直接采用了angular6,而后面该项目后面由我负责开发和维护,然后我又重新再学习了ng6,本以为有ng1的基础,学起来会好一些,然并卵,学习的曲线特别陡峭,但还是最后将ng6啃下来(很不情愿去学的,但没办法)。回归到项目,该项目没有引入其他组件库,所以很多基础组件都是自己开发(用ng开发那种酸爽很带劲),其中table组件让我思考了差不多两个星期,最后才开发出来,吐槽完毕,接下来就介绍一下我的做法,我的做法不一定最正确。

形式:

主要参考element里面的table组的格式:

vue:

<el-table :data="tableData">
  <el-table-column prop="date" label="日期"></el-table-column>
  <el-table-column label="操作">
   <template slot-scope="scope">
    <el-button @click="handleClick(scope.row)" type="text" size="small">查看</el-button>
   </template>
  </el-table-column>
 </el-table>

所以得到了angualr的table组件的格式:

<app-widget-table [data]="tableData">
  <app-widget-table-column prop="date" label="日期"></app-widget-table-column>

  <app-widget-table-column label="操作">
   <ng-template #scope let-row="scope">
      <ng-widget-button (click)="handleClick(row)" type="text" size="small">查看</el-button>
   </ng-template>
  </app-widget-table-column>
</app-widget-table>

在angular的table组件中,最为困难就是ng-template如何将作用域绑定到ng-widget-button组件中;

关键点知识讲解:

ng-content:
可以将父组件中所包含的所有子组件,都插入table组件中ng-container所在的位置,跟vue中的slot很像;

ng-container:
可以作为一个组件的模板,跟vue里面的template组件很像;

ng-template:
该东西,是整个组件中最为麻烦的一个东西,直接使用它,会没有任何效果,必须要和TemplateRef和ngTemplateOutlet一起使用,才有有效果,主要是作为模板并引入作用域,具体原理可以看一下官方文档(https://www.angular.cn/api)

TemplateRef:
主要是用来获取ng-template组件的引用;

ngTemplateOutlet:
将ng-template的内容在html页面展示出来,并绑定变量,就像vue中的router-view;

QueryList:
获取table组件中所有的内容指引;

ContentChildren:
内容映射的接口,针对多个子元素采用

ContentChild:
内容映射的接口,针对单个子元素采用

先对app-widget-table-column组件进行分析:
该组件的作用就是为了运输数据,并且引入内容,该组件本身是不会有任何操作和逻辑,就是一个运输工;

table-column.component.html:

<ng-container></ng-container>

table-column.component.ts:

import {Component, Input, Output, TemplateRef, ContentChild, AfterContentInit} from '@angular/core';

@Component({
  selector: 'app-widget-table-column',
  templateUrl: './table-column.component.html',
  styleUrls: ['./table-column.component.less'],
  preserveWhitespaces: false
})
export class TableColumnComponent implements AfterContentInit {
  constructor() {

  }

  @Input()
  label: string;

  @Input()
  prop: string;

  @Input()
  class: string;

  @Input()
  style: object;

  @ContentChild('scope') // 获取ng-template组件的一个本地变量,并修饰scope对象
  scope: TemplateRef<any>; // 获取ng-template的指引,主要是其内容,any表示该指可以是任何内容

  ngAfterContentInit(): void {}
}

table.component.html

<div>
  <div>
    <ng-content></ng-content> // 主要是用来引入整个table组件的内容,但不会在页面显示任何内容
  </div>

  <table class="table">
    <thead>
    <tr>
     <th *ngFor="let label of labelList">{{label}}</th>  // 类似于v-for,主要讲table-cloumn的所有label搜集,并展示
    </tr>
    </thead>

    <tbody *ngIf="data.length > 0">
    <ng-container *ngFor="let item of data; let i = index">
      <tr>
        <ng-container *ngFor="let row of tableColumn['_results']">
          <td *ngIf="row.prop" [ngStyle]="row.style" [ngClass]="row.class">{{item[row.prop]}}</td> // 直接展示

          <td *ngIf="row.scope" [ngStyle]="row.style" [ngClass]="row.class">
            <ng-container *ngTemplateOutlet="row.scope; context: {$implicit: {}, scope: data[i]}">
            </ng-container> // 展示ng-template的内容
          </td>
        </ng-container>
      </tr>
    </ng-container>
    </tbody>
  </table>

  <div *ngIf="data.length === 0" class="none-data">暂无数据!</div>
</div>

table.component.ts:

import {Component, OnInit, Input, Output, ContentChildren, AfterContentInit, ViewChild, AfterViewInit, QueryList} from '@angular/core';
import {TableColumnComponent} from '../table-column/table-column.component';

@Component({
  selector: 'app-widget-table',
  templateUrl: './table.component.html',
  styleUrls: ['./table.component.less'],
  preserveWhitespaces: false
})
export class TableComponent implements OnInit, AfterContentInit {
  constructor() {

  }

  @ContentChildren(TableColumnComponent)
  tableColumn: QueryList<TableColumnComponent>; // 获取table-cloumn组件的所有实例

  @Input()
  data: object[];

  labelList: string[] = [];

  ngOnInit(): void {
    if (!(this.data instanceof Array)) {
      throw new Error('the data into TableComonent must be Array!');
    }
  }

  ngAfterContentInit(): void {
    this.labelList = this.tableColumn['_results'].map(item => item.label);
  }
}

虽然看起来这两个组件的代码不多,但里面的逻辑却比较绕,这也证明了ng用起来十分难上手,不过真的称赞的是,ng采用ts和rx,用上手确实是比较爽。

这两个组件目前还是比较粗糙,功能和特性也不是特别多,只能满足一般表格的需求,后续会继续完善该组件以及其他项目中用ng来开发的基础组件,希望能沉淀出一套ng的组件库。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
bgsound 背景音乐 的一些常用方法及特殊用法小结
May 11 Javascript
电子商务网站上的常用的js放大镜效果
Dec 08 Javascript
JavaScript中__proto__与prototype的关系深入理解
Dec 04 Javascript
jquery eval解析JSON中的注意点介绍
Aug 23 Javascript
技术男用来对妹子表白的百度首页
Jul 23 Javascript
初步了解javascript面向对象
Nov 09 Javascript
jQuery 3.0 的变化及使用方法
Feb 01 Javascript
JavaScript中数组去除重复的三种方法
Apr 22 Javascript
JavaScript中自带的 reduce()方法使用示例详解
Aug 10 Javascript
Node.js连接MongoDB数据库产生的问题
Feb 08 Javascript
$.browser.msie 为空或不是对象问题的多种解决方法
Mar 19 Javascript
node全局变量__dirname与__filename的区别
Jan 14 Javascript
详解VUE里子组件如何获取父组件动态变化的值
Dec 26 #Javascript
JavaScript基础之静态方法和实例方法分析
Dec 26 #Javascript
微信小程序实现文字跑马灯
May 26 #Javascript
基于JavaScript canvas绘制贝塞尔曲线
Dec 25 #Javascript
基于js Canvas实现二次贝塞尔曲线
Dec 25 #Javascript
JavaScript实现小球沿正弦曲线运动
Sep 07 #Javascript
微信小程序使用二次贝塞尔曲线画波浪
Dec 25 #Javascript
You might like
PHP 开源框架22个简单简介
2009/08/24 PHP
php数据库操作model类(使用__call方法)
2016/11/16 PHP
PHP利用Socket获取网站的SSL证书与公钥
2017/06/18 PHP
php实现websocket实时消息推送
2018/03/30 PHP
PDO::beginTransaction讲解
2019/01/27 PHP
PHP实现关键字搜索后描红功能示例
2019/07/03 PHP
javascript cookies 设置、读取、删除实例代码
2010/04/12 Javascript
JavaScript获取XML数据附示例截图
2014/03/05 Javascript
jQuery实现预加载图片的方法
2015/03/17 Javascript
JavaScript实现动画打开半透明提示层的方法
2015/04/21 Javascript
jQuery中的Deferred和promise 的区别
2016/04/03 Javascript
js HTML5 Canvas绘制转盘抽奖
2020/09/13 Javascript
如何解决IONIC页面底部被遮住无法向上滚动问题
2016/09/06 Javascript
jQuery Ajax使用FormData上传文件和其他数据后端web.py获取
2017/06/11 jQuery
微信小程序实现简单input正则表达式验证功能示例
2017/11/30 Javascript
浅谈使用React.setState需要注意的三点
2017/12/18 Javascript
浅谈vue中关于checkbox数据绑定v-model指令的个人理解
2018/11/14 Javascript
element中Steps步骤条和Tabs标签页关联的解决
2020/12/08 Javascript
python 基本数据类型占用内存空间大小的实例
2018/06/12 Python
5款Python程序员高频使用开发工具推荐
2019/04/10 Python
Python 中使用 PyMySQL模块操作数据库的方法
2019/11/10 Python
python多线程实现代码(模拟银行服务操作流程)
2020/01/13 Python
快速解决jupyter notebook启动需要密码的问题
2020/04/21 Python
Django配置跨域并开发测试接口
2020/11/04 Python
以设计师精品品质提供快速时尚:PopJulia
2018/01/09 全球购物
影视艺术学院毕业生自荐信
2013/11/13 职场文书
优秀生推荐信范文
2013/11/28 职场文书
班组长安全生产职责
2013/12/16 职场文书
药剂专业学生求职信范文
2013/12/28 职场文书
服务之星获奖感言
2014/01/21 职场文书
《骆驼和羊》教学反思
2014/02/27 职场文书
2014年道德讲堂实施方案
2014/03/05 职场文书
2015年仓库管理工作总结
2015/05/25 职场文书
检讨书之工作不认真
2019/08/14 职场文书
php png失真的原因及解决办法
2021/10/24 PHP
CSS子盒子水平和垂直居中的五种方法
2022/07/23 HTML / CSS