关于前端选择器设计原理与实现

1 选择器的概念

选择器其实是一种较小数据源,供我们选择参数值使用,同时提供参数让选择器回显。选择器的表现形式多种多样,可以是模态弹出框,也可以是非模态扁平化弹出层。如我们常见的下拉选择器,下拉树形选择器

地址选择器。表现形式多种多样

2 选择器形式分类

既然选择器是提供一个数据源被用户选择,和回显用户选择的数据项,那么我们可以知道以下几点:

第一:被选中的数据结构,他可以是简单的数据类型,string,bool,或者number,也可以是复杂的array和object类型。对于array无外乎就是多选,object则为我们选中的对象

第二:复杂类型对象,对象的关系一般来说可以有简单对象,即独立性的存在,再有与其他对象组成一个array成为对象数组,或者他是一种树形结构,又或者他有前置条件,也就是说他依赖其他对象

第三:复杂选择器,复杂选择器是说我们选择的对象他是多个对象,依赖关系般存在,比如说地址选择器,他的第一级依赖是省级只有选择了省级才能选择市级,以此内推,呈现出一种前后依赖关系

3 选择器设计

我们并不关注选择器选择了什么具体数据结构,我们只知道我们的选择器统一风格,他需要回显什么对象,选择完成后返回了什么结果就可以了。至于选择器内部诸如列表,树形,前后依赖,查询过滤等等那都是由选择器内部完成。

4 选择器与表单

4.1 表单

我们知道选择器其实绝大多数与表单一起使用而存在,表单又需要具有输入数据的验证性,但是表单原始支持验证的控件只有那么几种,且不可以自定义,比如表单元素有input,select等等。

所以我们的选择器本身仅仅是选择数据源,自然的不能参与到表单内部中去。

4.2 与表单的关系

与表单的关系其实是与表单元素的关系,选择器仅仅是为表单元素 如input提供选择结果,而不参与结果的验证,这点必须要明白,那么有人估计会有疑问,如果我的选择器表现为比如为星级评价,可能就放了5颗星让你选择就是了,那么怎么验证用户没选呢?嗯是的,那么这个时候就要采取迂回的办法,那就是我们隐藏被验证的表单元素,比如我们使用一个input hidden来接收我们星级选择器的结果,那么自然的我们还是按原有表单验证的思路验证即可,两者之间本身是分离的。

5 基于angular的选择器类设计

我们可以封装一个基类

  1 /**
  2  * Created by Administrator on 2017-07-21.
  3  */
  4 import {Component, Input, Output, EventEmitter,AfterViewInit,OnDestroy,HostListener} from ‘@angular/core‘;
  5 import {Guid} from "../../utils/guid.util";
  6
  7
  8
  9 @Component({
 10   selector: ‘ba-popover‘,
 11   templateUrl: ‘./baPopover.html‘,
 12 })
 13 export class BaPopover implements AfterViewInit,OnDestroy{
 14
 15
 16   /**
 17    * 窗口唯一id标识
 18    * */
 19   @Input()  myid:string;
 20
 21   /**
 22    * 鼠标点击内容区域是否自动关闭
 23    * */
 24   @Input()  autoClose:boolean=true;
 25
 26   /**
 27    * 鼠是否关闭指示器
 28    * */
 29   isClose:boolean=false;
 30
 31   /**
 32    * 关闭事件
 33    * */
 34   @Output() onClosed = new EventEmitter<any>();
 35
 36   /**
 37    * 选择完成事件
 38    * */
 39   @Output() onSelectCompleted=new EventEmitter<any>();
 40
 41   /**
 42    * 视图初始化完成事件
 43    * */
 44   @Output() onAfterViewInit = new EventEmitter();
 45
 46
 47
 48   /**
 49    * 构造函数
 50    * */
 51   constructor(){
 52     this.myid=Guid.newGuid();
 53   }
 54
 55   /**
 56    * 重写视图初始化完成
 57    * */
 58   ngAfterViewInit(): void{
 59     this.onAfterViewInit.emit();
 60   }
 61
 62   /**
 63    * 重写窗口被回收
 64    * */
 65   ngOnDestroy():void{
 66
 67   }
 68   /**
 69    * 选择完成
 70    * */
 71   selectComplete():void{
 72
 73   }
 74   /**
 75    * 窗口显示
 76    * */
 77   public show():void{
 78     this.isClose=true;
 79   }
 80
 81   /**
 82    * 窗口关闭
 83    * */
 84   public close():void{
 85     this.isClose=!this.isClose;
 86     this.onClosed.emit(null);
 87   }
 88
 89   /**
 90    * 响应单击事件
 91    * */
 92   @HostListener(‘click‘) onClick(){
 93     if(this.autoClose)
 94     {
 95       this.isClose=!this.isClose;
 96     }
 97   }
 98
 99
100
101 }

对于子类来说我们仅仅需要关注我们选择了什么进而触发选择完成事件即可,然而有些遗憾的是在angular中对于html模板无法实现继承,所以只好每个模板都套用一个bootstrap的下拉选择容器

1 <div class="dropdown-menu"  [ngStyle]="{‘display‘:isClose?‘none‘:‘‘}">
2   <button class="dropdown-item" href>February 2017</button>
3   <a class="dropdown-item" href>March 2017</a>
4   <a class="dropdown-item" href>April 2017</a>
5   <button (click)="selectChange()" style="width: 400px;height: 200px;">Create danger alert</button>
6 </div>

如何弹出选择器,由于bootstrap提供的下拉菜单,在弹出后什么时候关闭没有接口进行操作,所以采用绑定方式动态显示弹出层,自然也就是上面这段html代码了。你们如何弹出来呢,弹出其实就是将html代码由

隐藏变为显示,我们在需要弹出的地方使用指令来为触发选择器出现的控件添加事件

 1 /**
 2  * Created by Administrator on 2017-07-27.
 3  */
 4 import {Directive, HostBinding,ElementRef,HostListener} from ‘@angular/core‘;
 5 import {GlobalState} from "../../../global.state";
 6
 7 @Directive({
 8   selector: ‘[baPop]‘
 9 })
10 export class BaPop {
11
12   constructor(private elementRef:ElementRef) {
13   }
14
15   public ngOnInit():void {
16   }
17
18   @HostListener(‘click‘) onClick() {
19     var navEle:any=$(this.elementRef.nativeElement);
20     var menus:any=navEle.parent().find(".dropdown-menu");
21     if(menus.length>0){
22       var menu=$(menus[0]);
23       menu.css(‘display‘,‘block‘);
24     }
25   }
26
27
28 }

自定义一个选择器

 1 /**
 2  * Created by Administrator on 2017-07-16.
 3  */
 4 import {Component, OnInit} from "@angular/core";
 5 import {ActivatedRoute, Router} from "@angular/router";
 6 import {FormArray, FormBuilder, FormControl, FormGroup, Validators} from "@angular/forms";
 7 import {UserDemoInfo} from "../../userdemo.model";
 8 import {UserDemoService} from "../../userdemo.service";
 9 import {BaPopover} from "../../../../theme/components/baPopover/baPopover.component";
10
11 @Component({
12   selector: ‘mypop‘,
13   templateUrl: ‘./my.pop.html‘
14 })
15 export class MyPop extends BaPopover{
16
17   constructor(){
18     super();
19     this.autoClose=false;
20   }
21
22   selectChange():void{
23     this.onSelectCompleted.emit(null);
24     this.close();
25   }
26
27 }
1 <div class="form-group row"  [class.has-danger]="formModel.get(‘account‘).touched && (formModel.hasError(‘minlength‘,‘account‘) || formModel.hasError(‘required‘,‘account‘))">
2               <label  class="col-form-label m-r-10">账号</label>
3               <div class="dropdown pull-left m-r-10 hidden-sm-down">
4                 <input class="dropdown-toggle"
5                        placeholder="碳储存" value="哈哈哈" baPop
6                        data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
7                 <mypop></mypop>
8               </div>
9             </div>
时间: 2024-08-05 18:50:08

关于前端选择器设计原理与实现的相关文章

BigPipe设计原理

高性能页面加载技术--BigPipe设计原理及Java简单实现 1.技术背景 动态web网站的历史可以追溯到万维网初期,相比于静态网站,动态网站提供了强大的可交互功能.经过几十年的发展,动态网站在互动性和页面显示效果上有了很大的提升,但是对于网站动态网站的整体页面加载架构没有做太大的改变.对于用户而言,页面的加载速度极大的影响着用户体验感.与静态网站不同,除了页面的传输加载时间外,动态网站还需考虑服务端数据的处理时间.像facebook这样大型的用户社交网站,必须考虑用户访问速度问题, 传统we

kafka入门:简介、使用场景、设计原理、主要配置及集群搭建(转)

问题导读: 1.zookeeper在kafka的作用是什么? 2.kafka中几乎不允许对消息进行"随机读写"的原因是什么? 3.kafka集群consumer和producer状态信息是如何保存的? 4.partitions设计的目的的根本原因是什么? 一.入门 1.简介 Kafka is a distributed,partitioned,replicated commit logservice.它提供了类似于JMS的特性,但是在设计实现上完全不同,此外它并不是JMS规范的实现.k

Atitit.ioc&#160;动态配置文件guice&#160;设计原理

Atitit.ioc 动态配置文件guice 设计原理 1. Bat启动时注入配置文件1 2. ioc调用1 3. Ioc 分发器 配合 apche  MethodUtils.invokeStaticMethod2 1. Bat启动时注入配置文件 SET JAVA_HOME=C:\Program Files\Java\jdk1.8.0_71 set  RESIN-HOME=c:\resin-4.0.22 set classpath=%classpath%;%RESIN-HOME%\lib\jas

Atitit.异常的设计原理与&#160;策略处理&#160;java&#160;最佳实践&#160;p93

Atitit.异常的设计原理与 策略处理 java 最佳实践 p93 1 异常方面的使用准则,答案是::2 1.1 普通项目优先使用异常取代返回值,如果开发类库方面的项目,最好异常机制与返回值都提供,由调用者决定使用哪种方式..2 1.2 优先把异常抛出到上层处理..异常本身就是为了方便把异常情况抛出到上层处理..2 1.3 对于 HYPERLINK \l _Toc6222 方法调用结果异常情况返回策略,最终会有四种策略状况,2 1.4 返回null  还是异常??2 2 异常的由来与设计3 2

Atitit ati&#160;licenseService &#160;&#160;&#160;设计原理

Atitit ati licenseService    设计原理 C:\0workspace\AtiPlatf\src_atibrow\com\attilax\license\LicenseX.java V1 更具时间超是 V2   按照时间慢的百分率.. V3 草案.. Laicense file ,hto sh aes time.. Invoke System.out.println( licenseX.isCanUse_byUsePercent("2016-05-01") );

以属性为核心驱动的 全领域通用架构设计原理 (简称:属性架构原理)

以属性为核心驱动的全领域通用架构设计原理 (简称:属性架构原理) 联系方式:13547930387 Email:[email protected] 一.个人声明 我,参加工作也有5年多了,是一名普通的不能在普通的程序员,一直在使用公司自己的产品进行开发,因此技术比较菜,此设计完全是按照自己天真的想法而设计的,如果有不合理或很搞笑的地方,请轻拍,由衷的希望大家能提出宝贵的意见: 根据此设计原理我也做了一个简单的(demo)架构来支撑和验证此理论的可行性,由于技术功底不太好,有不合理之处请大家谅解,

深入理解kafka设计原理

最近开研究kafka,下面分享一下kafka的设计原理.kafka的设计初衷是希望作为一个统一的信息收集平台,能够实时的收集反馈信息,并需要能够支撑较大的数据量,且具备良好的容错能力. 1.持久性 kafka使用文件存储消息,这就直接决定kafka在性能上严重依赖文件系统的本身特性.且无论任何OS下,对文件系统本身的优化几乎没有可能.文件缓存/直接内存映射等是常用的手段.因为kafka是对日志文件进行append操作,因此磁盘检索的开支是较小的;同时为了减少磁盘写入的次数,broker会将消息暂

BeanFactory容器的设计原理

XmlBeanFactory设计的类继承关系 1.BeanFactory接口提供了使用IoC容器的规范.在这个基础上,Spring还提供了符合这个IoC容器接口的一系列容器的实现供开发人员使用. 2.我们以XmlBeanFactory的实现为例来说明简单IoC容器的设计原理. 3.可以看到,作为一个简单IoC容器系列最底层实现的XmlBeanFactory,与我们在Spring应用中用到的上下文相比,有一个非常明显的特点:它只提供最基本的IoC容器的功能. 4.理解这一点有助于我们理解Appli

Scala函数式编程设计原理 第一课 编程范式(Programming Paradigms)

我使用Scala有一两年的时间了,这门语言仿佛有一种魔力,让人用过就不想放手.Scala给我的整个程序生涯带来了非常深刻的影响,让我学会了函数式编程,让我知道了世界上居然还有这么一种优雅.高效.强大的语言. Scala在国外已经非常流行,但是不知为何,在国内总是不温不火,在此,我特别想为Scala这门语言在国内的发展做一些事情.不才不敢谈Scala的编程经验,因为要成为Scala大神还有很长的路要走,只好翻译一份Scala视频教程以飨读者,大家发现有误的地方,请多多批评指教. 这个视频的作者是S