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 相关文章推荐
JQuery的ajax获取数据后的处理总结(html,xml,json)
Jul 14 Javascript
extjs 如何给column 加上提示
Jul 29 Javascript
60个很实用的jQuery代码开发技巧收集
Dec 15 Javascript
setTimeout内不支持jquery的选择器的解决方案
Apr 28 Javascript
JavaScript实现实时更新系统时间的实例代码
Apr 04 Javascript
vue如何从接口请求数据
Jun 22 Javascript
自适应布局meta标签中viewport、content、width、initial-scale、minimum-scale、maximum-scale总结
Aug 18 Javascript
详解微信小程序Page中data数据操作和函数调用
Sep 27 Javascript
完美解决手机网页中输入框被输入法遮挡的问题
Dec 19 Javascript
Node错误处理笔记之挖坑系列教程
Jun 05 Javascript
angularjs下ng-repeat点击元素改变样式的实现方法
Sep 12 Javascript
vue2之简易的pc端短信验证码的问题及处理方法
Jun 03 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入门教程 精简版
2009/12/13 PHP
ThinkPHP多语言支持与多模板支持概述
2014/08/22 PHP
使用Laravel中的查询构造器实现增删改查功能
2019/09/03 PHP
Laravel 自带的Auth验证登录方法
2019/09/30 PHP
JS控制表格隔行变色
2006/06/26 Javascript
JSON 入门指南 想了解json的朋友可以看下
2009/08/26 Javascript
Javascript中的相等与不等运算
2010/04/25 Javascript
浏览器解析js生成的html出现样式问题的解决方法
2012/04/16 Javascript
Js制作简单弹出层DIV在页面居中 中间显示遮罩的具体方法
2013/08/08 Javascript
Angular.js与Bootstrap相结合实现手风琴菜单代码
2016/04/13 Javascript
jQuery实现的tab标签切换效果示例
2016/09/05 Javascript
jquery实现输入框实时输入触发事件代码
2016/12/21 Javascript
javascript 删除数组元素和清空数组的简单方法
2017/02/24 Javascript
vue拦截器Vue.http.interceptors.push使用详解
2017/04/22 Javascript
微信小程序获取用户openId的实现方法
2017/05/23 Javascript
JavaScript实现动态添加Form表单元素的方法示例
2017/08/14 Javascript
微信小程序实现鼠标拖动效果示例
2017/12/01 Javascript
Javascript获取某个月的天数
2018/05/30 Javascript
详解小程序input框失焦事件在提交事件前的处理
2019/05/05 Javascript
微信小程序和H5页面间相互跳转代码实例
2019/09/19 Javascript
微信分享invalid signature签名错误踩过的坑
2020/04/11 Javascript
[01:30]DOTA2上海特锦赛现场采访 Loda倾情献唱
2016/03/25 DOTA
python获取文件版本信息、公司名和产品名的方法
2014/10/05 Python
使用Pyrex来扩展和加速Python程序的教程
2015/04/13 Python
Python中list初始化方法示例
2016/09/18 Python
Python2.7读取PDF文件的方法示例
2017/07/13 Python
Python中单例模式总结
2018/02/20 Python
pytorch中的inference使用实例
2020/02/20 Python
巴西宠物店在线:Geração Pet
2017/05/31 全球购物
毕业生个人求职信范例分享
2013/12/17 职场文书
电子专业毕业生自我鉴定
2014/01/22 职场文书
列车长先进事迹材料
2014/01/25 职场文书
宿舍违规用电检讨书
2014/02/16 职场文书
2014公司党员自我评价范文
2014/09/11 职场文书
销售员工作检讨书(推荐篇)
2014/10/18 职场文书
sql server删除前1000行数据的方法实例
2021/08/30 SQL Server