directive:

import { Directive, HostListener, HostBinding, ElementRef } from '@angular/core';

@Directive({
selector: '[credit-card]'
})
export class CreditCardDirective { @HostBinding('style.border')
border: string; @HostListener('input', ['$event'])
onKeyDown(event: KeyboardEvent) { const input = event.target as HTMLInputElement; let trimmed = input.value.replace(/\s+/g, '');
if (trimmed.length > ) {
trimmed = trimmed.substr(, );
} let numbers = [];
for (let i = ; i < trimmed.length; i += ) {
numbers.push(trimmed.substr(i, ));
} input.value = numbers.join(' '); this.border = '';
if (/[^\d]+/.test(trimmed)) {
this.border = '1px solid red';
} }
}

test:

import { DebugElement, Component } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing';
import { By } from '@angular/platform-browser';
import { CreditCardDirective } from './credit-card.directive'; TestBed.initTestEnvironment(
BrowserDynamicTestingModule,
platformBrowserDynamicTesting()
); @Component({
template: `
<input type="text" [value]="value" credit-card>
`
})
class TestComponent {
value = ;
} describe('CreditCardDirective', () => { let component: TestComponent;
let fixture: ComponentFixture<TestComponent>;
let el: DebugElement; beforeEach(() => {
TestBed.configureTestingModule({
declarations: [
CreditCardDirective,
TestComponent
]
});
fixture = TestBed.createComponent(TestComponent);
component = fixture.componentInstance;
el = fixture.debugElement;
}); it('should format the string with spaces', () => {
const directive = el.query(By.directive(CreditCardDirective)).nativeElement;
directive.value = '';
directive.dispatchEvent(new Event('input'));
expect(directive.value).toBe('4751 23');
directive.value = '';
directive.dispatchEvent(new Event('input'));
expect(directive.value).toBe('4751 2398 1201 9201');
}); it('should have a max-length of 16 characters', () => {
const directive = el.query(By.directive(CreditCardDirective));
const directiveEl = directive.nativeElement;
directiveEl.value = '';
directiveEl.dispatchEvent(new Event('input'));
expect(directiveEl.value).toBe('4751 2398 1201 9201');
directiveEl.value = 'abscdef';
directiveEl.dispatchEvent(new Event('input'));
const directiveInstance = directive.injector.get(CreditCardDirective);
expect(directiveInstance.border).toContain('1px solid red');
}); });

[Angular] Test Directive的更多相关文章

  1. [Angular 2] Directive intro and exportAs

    First, What is directive, what is the difference between component and directive. For my understandi ...

  2. 关于angular 自定义directive

    关于angular 自定义directive的小结 首先我们创建一个名为"expander"的自定义directive指令: angular.module("myApp& ...

  3. [Angular] Custom directive Form validator

    Create a directive to check no special characters allowed: import {Directive, forwardRef} from '@ang ...

  4. [Angular] Export directive functionalities by using 'exportAs'

    Directive ables to change component behaives and lookings. Directive can also export some APIs which ...

  5. [Angular] Using directive to create a simple Credit card validator

    We will use 'HostListener' and 'HostBinding' to accomplish the task. The HTML: <label> Credit ...

  6. angular service/directive

    <html class=" js cssanimations csstransitions" ng-app="phonecatApp" > < ...

  7. 一个Demo就懂的Angular之directive

    <body> <div ng-controller="myCtrl"> <hello-word></hello-word> < ...

  8. angular 中 directive中的多个指令

    <div ng-controller="ctrl1"> <superman weight length speed>superman</superma ...

  9. Angular中directive——scope选项与绑定策略,这个也经常迷惑的。

    开门见山地说,scope:{}使指令与外界隔离开来,使其模板(template)处于non-inheriting(无继承)的状态,当然除非你在其中使用了transclude嵌入,这点之后的笔记会再详细 ...

随机推荐

  1. 各种join一目了然: join 、inner join、left join 、right join、full join

    各种join一幅图一目了然 一下每幅图都是指: A * join B on A.id = B.in 这个帖子也非常形象.比較好:http://www.phpddt.com/db/inner_join- ...

  2. js13--对象、原型

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/stri ...

  3. ASP.NET MVC使用Ninject

    Ninject是一个快如闪电的,轻量级的.....依赖注入框架,呃呃呃,貌似很少用到,Ninject就是一个DI容器,作用是对ASP.NET MVC程序中的组件进行解耦 ,说到解耦其实也有其他的方式可 ...

  4. 设计模式六大原则(六): 开闭原则(Open Closed Principle)

    定义: 一个软件实体如类.模块和函数应该对扩展开放,对修改关闭. 问题由来: 在软件的生命周期内,因为变化.升级和维护等原因需要对软件原有代码进行修改时,可能会给旧代码中引入错误,也可能会使我们不得不 ...

  5. Method for address space layout randomization in execute-in-place code

    The present application relates generally to laying out address space for execute-in-place code and, ...

  6. A题之拼音转数字

    输入是一个仅仅包括拼音的字符串,请输出相应的数字序列.转换关系例如以下: 描写叙述: 拼音 yi er san si wu liu qi ba jiu       阿拉伯数字 1 2 3 4 5 6 ...

  7. 使用IPV6

    使用IPV6 知道IPV6已经很久了,但是一直没有使用过. 我使用的IPV4网络一般是 内网-->外网-->互联网,IPV6也不外乎这样,但是对IPV6而言,必须有它的"世界&q ...

  8. eclipse-ADT安装失败经验

    今天下载了一个eclipse,结果ADT死活安装不成功,网上试了很多的方法,最后还是失败了.最后听从同事的建议,直接使用adt-bundle了.这个环境基本上都是配置好的. 下载地址 http://w ...

  9. 【习题 6-2 UVA - 712】S-Trees

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] dfs模拟一下就好. 先预处理一个dfs. 搞出来x叶子节点它的值是什么 [代码] /* 1.Shoud it use long l ...

  10. 洛谷 P1170 兔八哥与猎人

    P1170 兔八哥与猎人 题目描述 兔八哥躲藏在树林旁边的果园里.果园有M × N棵树,组成一个M行N列的矩阵,水平或垂直相邻的两棵树的距离为1.兔八哥在一棵果树下. 猎人背着猎枪走进了果园,他爬上一 ...