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 相关文章推荐
jquery的ajax从纯真网(cz88.net)获取IP地址对应地区名
Dec 02 Javascript
jQuery对表单的操作代码集合
Apr 06 Javascript
$.format,jquery.format 使用说明
Jul 13 Javascript
jQuery实现列表内容的动态载入特效
Aug 08 Javascript
分享纯手写漂亮的表单验证
Nov 19 Javascript
详解JavaScript 中的 replace 方法
Jan 01 Javascript
JavaScript中解决多浏览器兼容性23个问题的快速解决方法
May 19 Javascript
JavaScript 限制文本框不可输入英文单双引号的方法
Dec 20 Javascript
node.js中实现kindEditor图片上传功能的方法教程
Apr 26 Javascript
vue初始化动画加载的实例
Sep 01 Javascript
JavaScript代码调试方法实例小结
Jan 05 Javascript
jQuery选择器之基本选择器用法实例分析
Feb 19 jQuery
详解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将数据库导出成excel的方法
2010/05/07 PHP
PHP面向对象之旅:深入理解static变量与方法
2014/01/06 PHP
Laravel 中获取上一篇和下一篇数据
2015/07/27 PHP
PHP正则之正向预查与反向预查讲解与实例
2020/04/06 PHP
JavaScript入门之事件、cookie、定时等
2011/10/21 Javascript
JavaScript高级程序设计(第3版)学习笔记 概述
2012/10/11 Javascript
Firefox中使用outerHTML的2种解决方法
2014/06/07 Javascript
JavaScript onkeydown事件入门实例(键盘某个按键被按下)
2014/10/17 Javascript
javascript+HTML5的canvas实现七夕情人节3D玫瑰花效果代码
2015/08/04 Javascript
javascript实现input file上传图片预览效果
2015/12/31 Javascript
jQuery+ajax实现实用的点赞插件代码
2016/07/06 Javascript
node 命令方式启动修改端口的方法
2018/05/12 Javascript
最后说说Vue2 SSR 的 Cookies 问题
2018/05/25 Javascript
jQuery实现的简单对话框拖动功能示例
2018/06/05 jQuery
webpack 如何同时输出压缩和未压缩的文件的实现步骤
2020/06/05 Javascript
vue 实现根据data中的属性值来设置不同的样式
2020/08/04 Javascript
Python之eval()函数危险性浅析
2014/07/03 Python
用Python编写分析Python程序性能的工具的教程
2015/04/01 Python
用实例分析Python中method的参数传递过程
2015/04/02 Python
Python的Flask框架中SQLAlchemy使用时的乱码问题解决
2015/11/07 Python
Python自动化开发学习之三级菜单制作
2017/07/14 Python
python3去掉string中的标点符号方法
2019/01/22 Python
Mac在python3环境下安装virtualwrapper遇到的问题及解决方法
2019/07/09 Python
kali中python版本的切换方法
2019/07/11 Python
python multiprocessing多进程变量共享与加锁的实现
2019/10/02 Python
pycharm 2018 激活码及破解补丁激活方式
2020/09/21 Python
Python实现SMTP邮件发送
2020/06/16 Python
工业设计专业推荐信
2013/10/29 职场文书
自主招生自荐信格式
2013/12/03 职场文书
关于人生的感言
2014/01/17 职场文书
趣味运动会活动方案
2014/02/12 职场文书
副科级后备干部考察材料
2014/05/15 职场文书
消防工作实施方案
2014/06/09 职场文书
革命英雄事迹演讲稿
2014/09/13 职场文书
2014乡镇班子个人对照检查材料思想汇报
2014/09/26 职场文书
学习经验交流会策划书
2015/11/02 职场文书