Angular6 用户自定义标签开发的实现方法


Posted in Javascript onJanuary 08, 2019

2018年4月23随着angular6 发布,我们可以看到在其官方手册中的模板元素章节中增加了一个Element 条目(中文),通过说明我们可以知道这个功能可以帮助我们将angular以html标签的形式嵌入到非angular的页面环境中。下面我们就通过一个简单的例子演示Angular6中的这一新功能。

新建angular工程

通过ng命令新建custom-tag工程

ng new custom-tag

cli新建完相应文件后会通过npm下载所信赖的包,完成后进入目录验证工作空间是否正常。

$cd custom-tag
$ng serve --open

--open参数的作用是直接打开浏览器,也可以通过浏览器中直接输入localhost:4200。

Angular6 用户自定义标签开发的实现方法

增加标签功能

修改app.component.html 内容

<!--The content below is only a placeholder and can be replaced.-->
<!--
<div style="text-align:center">
 <h1>
  Welcome to {{ title }}!
 </h1>
 <img width="300" alt="Angular Logo" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTAgMjUwIj4KICAgIDxwYXRoIGZpbGw9IiNERDAwMzEiIGQ9Ik0xMjUgMzBMMzEuOSA2My4ybDE0LjIgMTIzLjFMMTI1IDIzMGw3OC45LTQzLjcgMTQuMi0xMjMuMXoiIC8+CiAgICA8cGF0aCBmaWxsPSIjQzMwMDJGIiBkPSJNMTI1IDMwdjIyLjItLjFWMjMwbDc4LjktNDMuNyAxNC4yLTEyMy4xTDEyNSAzMHoiIC8+CiAgICA8cGF0aCAgZmlsbD0iI0ZGRkZGRiIgZD0iTTEyNSA1Mi4xTDY2LjggMTgyLjZoMjEuN2wxMS43LTI5LjJoNDkuNGwxMS43IDI5LjJIMTgzTDEyNSA1Mi4xem0xNyA4My4zaC0zNGwxNy00MC45IDE3IDQwLjl6IiAvPgogIDwvc3ZnPg==">
</div>
<h2>Here are some links to help you start: </h2>
<ul>
 <li>
  <h2><a target="_blank" rel="noopener" href="https://angular.io/tutorial" rel="external nofollow" >Tour of Heroes</a></h2>
 </li>
 <li>
  <h2><a target="_blank" rel="noopener" href="https://github.com/angular/angular-cli/wiki" rel="external nofollow" >CLI Documentation</a></h2>
 </li>
 <li>
  <h2><a target="_blank" rel="noopener" href="https://blog.angular.io/" rel="external nofollow" >Angular blog</a></h2>
 </li>
</ul>
-->
<input #inputtext type="text" placeholder="条目">
<input type="button" value="增加" (click)="addItem(inputtext.value)">
<ul>
  <li *ngFor="let item of items">{{item}}</li>
</ul>

为对应的类增加 addItem()方法,向类中的条目集合(items)增加用户输入的一个条目。

import { Component } from '@angular/core';

@Component({
 selector: 'app-root',
 templateUrl: './app.component.html',
 styleUrls: ['./app.component.css']
})
export class AppComponent {
 
 addItem(item:string){
  console.log(`${item} to be added!`);
  this.items.push(item); 
 }

 items:string[] =[];
}

小结

到目前为止这是一个普通的angular应用,通过增加按钮,要以向列表中增加元素。

Angular6 用户自定义标签开发的实现方法

应用状态

将完成内容转换为自定义标签

增加@angular/comonents信赖

$ng add @angular/elements

修改app.module.ts

从包中导入相关依赖:

import { Injector} from '@angular/core';
import { createCustomElement } from '@angular/elements';

将AppComponent改为动态组件,并通过createCustomElement()注册AppComponent为custom-items

import { BrowserModule } from '@angular/platform-browser';
import { NgModule,Injector } from '@angular/core';

import { createCustomElement } from '@angular/elements';

import { AppComponent } from './app.component';

@NgModule({
 declarations: [
  AppComponent
 ],
 imports: [
  BrowserModule
 ],
 providers: [],
 //bootstrap: [AppComponent]
 entryComponents : [
  AppComponent
 ]
})
export class AppModule {
 constructor(private injector : Injector){
  const cust_tag = createCustomElement(AppComponent, {injector : this.injector});
  customElements.define('custom-items',cust_tag);
 }

 ngDoBootstrap() {}
 }

修改index.html页面

<!doctype html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <title>CustomTag</title>
  <base href="/" rel="external nofollow" >

  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico" rel="external nofollow" >
</head>

<body>
  <!--<app-root></app-root>-->
  <custom-items></custom-items>
</body>

</html>

页面重新出现在浏览器中了,功能也同先前一模一样。

由于浏览器版本的原因可能会出现下面错误,无法创建自定义标签

elements.js:384 Uncaught TypeError: Failed to construct 'HTMLElement': Please use the 'new' operator, this DOM object constructor cannot be called as a function.
    at NgElementImpl.NgElement [as constructor] (elements.js:384)
    at new NgElementImpl (elements.js:420)
    at new AppModule (app.module.ts:24)
    at _createClass (core.js:8421)
    at _createProviderInstance (core.js:8393)
    at initNgModule (core.js:8326)
    at new NgModuleRef_ (core.js:9052)
    at createNgModuleRef (core.js:9041)
    at Object.debugCreateNgModuleRef [as createNgModuleRef] (core.js:10866)
    at NgModuleFactory_.push../node_modules/@angular/core/fesm5/core.js.NgModuleFactory_.create (core.js:11583)

可以通过修改tsconfig.json中的构建目标至es6解决该问题

{
 "compileOnSave": false,
 "compilerOptions": {
  "baseUrl": "./",
  "outDir": "./dist/out-tsc",
  "sourceMap": true,
  "declaration": false,
  "moduleResolution": "node",
  "emitDecoratorMetadata": true,
  "experimentalDecorators": true,
  "target": "es6",
  "typeRoots": [
   "node_modules/@types"
  ],
  "lib": [
   "es2017",
   "dom"
  ]
 }
}

增加外部事件

通过output 可以为自定义标签增加自定义事件

import { Component,Output, EventEmitter } from '@angular/core';

@Component({
 selector: 'app-root',
 templateUrl: './app.component.html',
 styleUrls: ['./app.component.css']
})
export class AppComponent {
 
 @Output() itemAdded:EventEmitter<string> = new EventEmitter<string>();
 addItem(item:string){
  console.log(`${item} to be added!`);
  this.items.push(item); 
  // 向外发送自定义事件
  this.itemAdded.emit(item);
 }

 items:string[] =[];
}

在客户端页面可以通过自定义标签对象的addEventListener()方法增加自定义事件响应,通过 event.detail可以获取到angular内部发送的内容

<script>
    var items = document.querySelector('custom-items');

    items.addEventListener('itemAdded', (event) => {
      console.log(event);
    })
  </script>

完结与发布

在package.json中增加发布脚本

"scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build --prod --output-hashing none",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e"
  },

通过npm run build 执行构建,由于我们关闭了文件名hash,得到的输出目录内容如下:

liunan@liunan-desktop:~/webDev/custom-tag$ ls ./dist/custom-tag/
3rdpartylicenses.txt favicon.ico index.html main.js polyfills.js runtime.js scripts.js styles.css

我们可以看到输出的index.html文件中采用如下方式引用了定义标签的输出,如果其他用户使用会非常不便,

<script type="text/javascript" src="runtime.js"></script>
<script type="text/javascript" src="polyfills.js"></script>
<script type="text/javascript" src="scripts.js"></script>
<script type="text/javascript" src="main.js"></script>

我们可以通过使用cat命令将这些文件按照上面顺序合并成一个文件

$cat runtime.js polyfills.js scripts.js main.js > custom-items.js

这样用户就可以引用单个文件来使用我们制做的custom-items了。

一定注记合并文件的次序,需要严格按照上述次序进行,否则脚本可能不能正常工作。

示例代码

在线示例

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

Javascript 相关文章推荐
asp 的 分词实现代码
May 24 Javascript
jquery实现textarea输入字符控制(仿微博输入控制字符)
Apr 26 Javascript
键盘KeyCode值列表汇总
Nov 26 Javascript
对table和ul实现js分页示例分享
Feb 24 Javascript
jQuery实现仿新浪微博浮动的消息提示框(可智能定位)
Oct 10 Javascript
动态创建按钮的JavaScript代码
Jan 29 Javascript
javascript特殊日历控件分享
Mar 07 Javascript
基于JavaScript实现微信抢红包功能
Jul 20 Javascript
Vue2.0用 watch 观察 prop 变化(不触发)
Sep 08 Javascript
javascript按顺序加载运行js方法
Dec 01 Javascript
angularjs使用div模拟textarea文本框的方法
Oct 02 Javascript
eslint 的三大通用规则详解
May 16 Javascript
JS实现的获取银行卡号归属地及银行卡类型操作示例
Jan 08 #Javascript
关于微信小程序登录的那些事
Jan 08 #Javascript
Vue2.x Todo之自定义指令实现自动聚焦的方法
Jan 08 #Javascript
关于React动态加载路由处理的相关问题
Jan 07 #Javascript
vue+iview 兼容IE11浏览器的实现方法
Jan 07 #Javascript
详解Vue iview IE浏览器不兼容报错(Iview Bable polyfill)
Jan 07 #Javascript
利用React Router4实现的服务端直出渲染(SSR)
Jan 07 #Javascript
You might like
php $_ENV为空的原因分析
2009/06/01 PHP
thinkPHP实现表单自动验证
2014/12/24 PHP
Yii框架扩展CGridView增加导出CSV功能的方法
2017/05/24 PHP
JavaScript 以对象为索引的关联数组
2010/05/19 Javascript
jQuery遍历之next()、nextAll()方法使用实例
2014/11/08 Javascript
js一维数组、多维数组和对象的混合使用方法
2016/04/03 Javascript
JS实现图片剪裁并预览效果
2016/08/12 Javascript
原生JS实现网络彩票投注效果
2016/09/25 Javascript
详解jQuery的表单验证插件--Validation
2016/12/21 Javascript
获取当前月(季度/年)的最后一天(set相关操作及应用)
2016/12/27 Javascript
微信小程序日历组件calendar详解及实例
2017/06/08 Javascript
vue地区选择组件教程详解
2018/05/04 Javascript
vue elementUI tree树形控件获取父节点ID的实例
2018/09/12 Javascript
nodejs读取本地中文json文件出现乱码解决方法
2018/10/10 NodeJs
Jquery获取radio选中值实例总结
2019/01/17 jQuery
微信小程序使用map组件实现解析经纬度功能示例
2019/01/22 Javascript
JavaScript实现的九种排序算法
2019/03/04 Javascript
解决Ant Design Modal内嵌Form表单initialValue值不动态更新问题
2020/10/29 Javascript
使用typescript快速开发一个cli的实现示例
2020/12/09 Javascript
[04:03]2014DOTA2西雅图国际邀请赛 LGD战队巡礼
2014/07/07 DOTA
Python yield使用方法示例
2013/12/04 Python
django与vue的完美结合_实现前后端的分离开发之后在整合的方法
2019/08/12 Python
python+opencv3生成一个自定义纯色图教程
2020/02/19 Python
解决Jupyter因卸载重装导致的问题修复
2020/04/10 Python
Python telnet登陆功能实现代码
2020/04/16 Python
CSS3 实现弹跳的小球动画
2020/10/26 HTML / CSS
网络通讯中,端口有什么含义,端口的取值范围
2012/11/23 面试题
网络体系结构及协议的定义
2014/03/13 面试题
《蜗牛的奖杯》教后反思
2014/04/24 职场文书
需求分析说明书
2014/05/09 职场文书
公务员群众路线专题民主生活会发言材料
2014/09/17 职场文书
先进个人推荐材料
2014/12/29 职场文书
写给老师的感谢信
2015/01/20 职场文书
小班下学期个人总结
2015/02/12 职场文书
晚会主持人开场白台词
2015/05/28 职场文书
win10此电脑打不开怎么办 win10双击此电脑无响应的解决办法
2022/07/23 数码科技