Angular Elements 组件在非angular 页面中使用的DEMO

Stella981
• 阅读 675

一、Angular Elements 介绍

      Angular Elements 是伴随Angular6.0一起推出的新技术。它借助Chrome浏览器的ShadowDom  API,实现一种自定义组件。 这种组件可以用Angular普通组件的开发技术进行编写,学习成本低,当它构建好后生成一个打包的js文件。如果页面引入该Js文件 ,就相当于在页面中新增了一个标签,所以在任意框架中都可以使用新标签,就像它是原生div一样。

       ShadowDom  API  是谷歌自己一直强推的API,也一直未标准化的技术。2013年推出的chrome25中,就支持Shadow Dom v0的API,至今都没有其它浏览器附和谷歌的。2016年的chrome53时,谷歌又推出了Shadow Dom v1的API。v1版本似乎将成正式标准,就连Edge都是都示正在考虑。无论v0,v1版本,现在都是草案的状态,距离正式标准还很远。幸运的是,现在有个项目@webcomponents/custom-elements提供polyfill技术方案,能让其它浏览器提前用上该技术。

二、Angular Elements 使用实战

     前不久看到项目**angular-elements-dashboard :**支持动态加载模块和动态加载外部的模块。其中加载动态外部模块就是先编译一个angular elements项目,然后动态把该bundle.js插入到页面中。于是我就尝试一下,看这个构建的angular elements 文件到底如果引入一个空白的页面中,引入后的组件在浏览器中又是如何呈现的。

    Demo 源文件 在 码云:https://gitee.com/40288193/Angualr-elements-demo Angular Elements 组件在非angular 页面中使用的DEMO

     页面结构:     

Angular Elements 组件在非angular 页面中使用的DEMO

**demo.html                                                                                   **        

 主文件是一个标准的html5页面

external-dashboard-tile.emulated.js

external-dashboard-tile.native.js 

 是angular elements 用两种组件封装的方式打包的结果,分别是ViewEncapsulation.Emulated和                 ViewEncapsulation.Native封装。它们也是今天的测试主要对象。

custom-elements.min.js 

@webcomponents/custom-elements 的文件,是Shadow Dom v1 的polyfill文件 。 
如果用chrome53以后的浏览器的话,可以不引入它。如果是其它浏览器,它是必须的。

native-shim.js 

如果angular elements项目打包时,tsconfig.json中,
编译参数 **target: "es5"**时,  所有的class都被编译为function,此时就必须引入该文件。
编译参数 **target:"es2015"**或更高级的模块时,则不需要引入它。
根本原因是,Shadow Dom v1的api 只支持自定义元素是一个class类型,不能是一个function。

zone.js   

 angular依赖的文件

页面代码:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Angular Elements 演示Demo</title>
  <link rel="stylesheet" href="https://my.oschina.net//u/1540190/blog/1929672/bootstrap.min.css">
</head>
<body class="container">
  <h1>Angular Elements 演示Demo</h1>
  <div class="row">
    <h3>原生JS插入一个自定义元素</h3>
    <div id="byJs"></div>
  </div>
  <div class="row">
    <h3>用jqyery插入一个自定义元素</h3>
    <div id="byJquery"></div>
  </div>
  <script src="https://my.oschina.net//u/1540190/blog/1929672/zone.js"></script>
  <script src="https://my.oschina.net//u/1540190/blog/1929672/custom-elements.min.js"></script>
  <script src="https://my.oschina.net//u/1540190/blog/1929672/native-shim.js"></script>
  <script src="https://my.oschina.net//u/1540190/blog/1929672/jquery.min.js"></script>
  <script src="https://my.oschina.net//u/1540190/blog/1929672/external-dashboard-tile.native.js"></script>
  <script>
    // 新引入的external-dashboard-tile元素,  它有三个属性a,b,c,它展示为一个表格

    // 原生JS插入
    const dom = document.createElement("external-dashboard-tile"), byJs = document.getElementById("byJs");
    dom.classList.add("col-sm-2");
    dom.setAttribute('a', '' + Math.round(Math.random() * 100));
    dom.setAttribute('b', '' + Math.round(Math.random() * 100));
    dom.setAttribute('c', '' + Math.round(Math.random() * 100));

    byJs.appendChild(dom);

    // Jquery 插入
    const $dom = $("<external-dashboard-tile>"), $byJquery = $("#byJquery");
    $dom.addClass("col-sm-2");
    $dom.attr("a", Math.round(Math.random() * 100));
    $dom.attr("b", Math.round(Math.random() * 100));
    $dom.attr("c", Math.round(Math.random() * 100));

    $byJquery.append($dom);

    // 定时去修改两个表格的某个列
    setInterval(function () {
      dom.setAttribute('b', '' + Math.round(Math.random() * 100));
      $dom.attr("a", Math.round(Math.random() * 100));
    }, 2000)
  </script>
</body>

</html>

效果:

Angular Elements 组件在非angular 页面中使用的DEMO   注意:上下两个组件中,a,b两个列是定时变化的。

三、Angular Elements应用页面的分析

        代码逻辑估计小学生也看的懂了,分别用原生JS 和 jquery 两种技术,生成元素,并且设置元素的class 和 属性,最后插入到页面上。   最后写个定时器,分别用两种技术定时修改它们的一个属性

       当我引入external-dashboard-tile.emulated.js  文件时,它是angular模拟组件的方式插入页面的,就是自定义标签里直接嵌入了div,这种模式并不是真正的Shadow Dom ,它只是一种模拟手段,它通过引入_ng_content-c0的属性空间隔离css 样式。

Angular Elements 组件在非angular 页面中使用的DEMO

当我引入external-dashboard-tile.native.js  文件时,就是用原生的方式引入了,看效果,页面上有了 #showdow-root节点,并且外部的bootstrap样式传递不进去了,造成组件的样式全无。

Angular Elements 组件在非angular 页面中使用的DEMO

     总结一下,通过使用两个种方式操作自定义元素和以前学习的内置元素的概念一模一样。  那么就是说一个angular elements技术打包好的组件可以: build once ,run any framework!  这个黑科技还是让人惊喜的。  

     Angular Elements的开发技术和Angular普通组件是一致的,像Input属性,Output事件,  依赖注入的支持, 内容投影的支持(这个好像要用 来做)  ,总之并没有因为 Angular Elements需要脱离ng环境,没有Module 没有Route等支持,它就阉割功能,添加限制。没有,全部没有, 这一点谷歌还是良心。

四、Angular Elements应用后记

       组件封装方式分别是native,emulated 。按照以前看的文章说明,Native模式其实用的是Shadow Dom v0,并不是最新的技术,在2018.7.25号的6.1.0升级中,它又引入了新的封装方式ViewEncapsulation.Shadow 。它的目的是为了不改变Native的模式情况下,引入最新的Shadow Dom v1技术 ,而Native已经过时,不鼓励使用。详见  (#24718

      现在这种打包模式,对于一个最简单的组件,打包后体积是189kb,是非常之大的。据说伴随angular 7推出的ivy 渲染引擎能大大减小组件的构建体积,忘在哪个视频中看到说打包后可到10kb的量级,但现在找不到该说法的来源。现在angular的commit中,有一半都是关于ivy的提交,只需要大家静等angular 7.0的到来了! 

       现在相关资料还比较少,我也是看youtube视频学习的相关介绍,下面给大家几个学习资料

官方文档:https://www.angular.cn/guide/elements

视频 Elements in v6 and Beyond :https://www.youtube.com/watch?v=Z1gLFPLVJjY

示例项目angular-elements-dashboardhttps://github.com/manfredsteyer/angular-elements-dashboard

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Easter79 Easter79
3年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
10个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这