Angular6 写一个简单的Select组件示例


Posted in Javascript onAugust 20, 2018

Select组件目录结构

/src
  /app
    /select
    /select.ts
    /select.html
    /select.css
    /options.ts
    /index.ts
//select.ts
import { Component, ContentChildren, ViewChild, Input, Output, EventEmitter, QueryList, HostListener } from '@angular/core';
import { NzOptionDirective } from './option';
@Component({
 selector: 'nz-select',
 templateUrl: './select.html',
 styleUrls: ['./select.css']
})
export class NzSelectComponent {
 @Input() isOpen: boolean;
 @Input() value: string;
 @Output() valueChange = new EventEmitter<any>();
 label: string;
 @ContentChildren(NzOptionDirective, { descendants: true }) options: QueryList<NzOptionDirective>;

 ngAfterContentInit() {
  this.options.forEach(option => {
   option.select.subscribe(() => {
    this.value = option.value;
    this.label = option.renderLabel();
    this.options.map(r => r.isSelected = false);
    option.isSelected = true;
    this.valueChange.emit(option.value);
   })
   setTimeout(() => {
    option.isSelected = option.value === this.value;
    if (option.isSelected) {
     this.label = option.renderLabel();
     this.valueChange.emit(option.value);
    }
   });
  })
 }

 @HostListener('click')
 onClick() {
  this.isOpen = !this.isOpen;
 }
}
//select.html
<ng-content *ngIf="isOpen"></ng-content>
<div *ngIf="!isOpen">{{label}}</div>
//select.css
:host {
 display: inline-block;
 border: 1px solid;
 cursor: pointer;
 text-align: center;
 border-radius: 4px;
}

:host .current{
 padding:5px 10px;
 background:red;
 color:#FFF;
 text-align: center;
 width:40px;
 outline: none;
 border: none;
}

::ng-deep div:not(.current):hover{
 background:green;
 color:#FFF;
}

::ng-deep .selected {
 font-weight: 700;
 background: red;
 color:#FFF;
}
//options.ts
import { Directive,HostBinding,HostListener,Input,Output,ElementRef,EventEmitter} from '@angular/core';

@Directive({
 selector:'[nzOption]'
})
export class NzOptionDirective{
 @Input() value:string;
 constructor(private el:ElementRef){}
 @Output() select = new EventEmitter<any>();
 
 @HostBinding("class.selected")
 isSelected: boolean;

 renderLabel(){
  return (this.el.nativeElement.textContent || "").trim();
 }

 @HostListener('click')
 onClick(){
  this.select.emit();
 }

}
//index.ts
import { NzOptionDirective } from './option';
import { NzSelectComponent } from './select';
export const components = [
 NzSelectComponent,
 NzOptionDirective
];

应用 Select 组件

结构

/src
  /app/
    /app.module.ts
    /app.component.ts
    /app.component.html
//app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { CommonModule } from '@angular/common';
import {components} from './select';
import { AppComponent } from './app.component';
@NgModule({
 imports:   [ BrowserModule, FormsModule,CommonModule ],
 declarations: [ AppComponent,...components],
 bootstrap:  [ AppComponent ]
})
export class AppModule { }
//app.component.ts
import { Component } from '@angular/core';

@Component({
 selector: 'my-app',
 templateUrl: './app.component.html',
 styleUrls: ['./app.component.css']
})
export class AppComponent {
 name = 'Angular';

 defaultValue: any = 'value5'

 menus: any[] = [];

 ngOnInit() {
  for (let i = 0; i <= 6; i++) {
   this.menus.push({
    value: 'value' + i,
    label: 'item' + i
   })
  }
 }
}
//app.component.html
<nz-select [(value)]="defaultValue" [isOpen]="false">
 <div nzOption *ngFor="let m of menus" [value]="m.value">{{m.label}}</div>
</nz-select>
<pre>
 select value is <b>{{defaultValue|json}}</b>
</pre>

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

Javascript 相关文章推荐
11款基于Javascript的文件管理器
Oct 25 Javascript
JS分割字符串并放入数组的函数
Jul 04 Javascript
ASP.NET jQuery 实例3 (在TextBox里面阻止复制、剪切和粘贴事件)
Jan 13 Javascript
jQuery中使用data()方法读取HTML5自定义属性data-*实例
Apr 11 Javascript
AngularJS ngModel实现指令与输入直接的数据通信
Sep 21 Javascript
利用Js+Css实现折纸动态导航效果实例源码
Jan 25 Javascript
node koa2实现上传图片并且同步上传到七牛云存储
Jul 31 Javascript
vue实现点击图片放大效果
Aug 15 Javascript
浅谈vue中使用图片懒加载vue-lazyload插件详细指南
Oct 23 Javascript
Vue cli 引入第三方JS和CSS的常用方法分享
Jan 20 Javascript
vue-cli3+typescript初体验小结
Feb 28 Javascript
Vue 实现监听窗口关闭事件,并在窗口关闭前发送请求
Sep 01 Javascript
Layer弹出层动态获取数据的方法
Aug 20 #Javascript
layui 给数据表格加序号的方法
Aug 20 #Javascript
解决LayUI表单获取不到data的问题
Aug 20 #Javascript
Layui数据表格之获取表格中所有的数据方法
Aug 20 #Javascript
解决layui上传文件提示上传异常,实际文件已经上传成功的问题
Aug 19 #Javascript
解决layui中table异步数据请求不支持自定义返回数据格式的问题
Aug 19 #Javascript
Vue常用指令详解分析
Aug 19 #Javascript
You might like
PHP5.4中json_encode中文转码的变化小结
2013/01/30 PHP
ThinkPHP的截取字符串函数无法显示省略号的解决方法
2014/06/25 PHP
浅析ThinkPHP的模板输出功能
2014/07/01 PHP
PHP经典设计模式之依赖注入定义与用法详解
2019/05/21 PHP
jquery.AutoComplete.js中文修正版(支持firefox)
2010/04/09 Javascript
修复IE9&amp;safari 的sort方法
2011/10/21 Javascript
Json实现异步请求提交评论无需跳转其他页面
2014/10/11 Javascript
jquery实现键盘左右翻页特效
2015/04/30 Javascript
JavaScript动态添加style节点的方法
2015/06/09 Javascript
JavaScript事件类型中UI事件详解
2016/01/14 Javascript
AngularJS中ng-class用法实例分析
2017/07/06 Javascript
详解Webpack DLL用法以及功能
2017/07/11 Javascript
使用JQ完成表格隔行换色的简单实例
2017/08/25 Javascript
vue mintui-Loadmore结合实现下拉刷新和上拉加载示例
2017/10/12 Javascript
webpack+vue中使用别名路径引用静态图片地址
2017/11/20 Javascript
浅谈vue单一组件下动态修改数据时的全部重渲染
2018/03/01 Javascript
layui多iframe页面控制定时器运行的方法
2019/09/05 Javascript
原生js基于canvas实现一个简单的前端截图工具代码实例
2019/09/10 Javascript
vue使用自定义事件的表单输入组件用法详解【日期组件与货币组件】
2020/06/01 Javascript
vue 导航锚点_点击平滑滚动,导航栏对应变化详解
2020/08/10 Javascript
python标准日志模块logging的使用方法
2013/11/01 Python
Python下使用Psyco模块优化运行速度
2015/04/05 Python
独特的python循环语句
2016/11/20 Python
python 实现在txt指定行追加文本的方法
2018/04/29 Python
Linux下通过python获取本机ip方法示例
2019/09/06 Python
学python安装的软件总结
2019/10/12 Python
TensorFlow tensor的拼接实例
2020/01/19 Python
Jupyter 无法下载文件夹如何实现曲线救国
2020/04/22 Python
python中的时区问题
2021/01/14 Python
美国女孩洋娃娃店:American Girl
2017/10/24 全球购物
2014年国庆标语
2014/06/30 职场文书
乡镇党委书记第三阶段个人整改措施
2014/09/16 职场文书
质量整改通知单
2015/04/21 职场文书
社团招新宣传语
2015/07/13 职场文书
初中生物教学反思
2016/02/20 职场文书
python 远程执行命令的详细代码
2022/02/15 Python