简体   繁体   中英

Attribute directives angular

I created an attribute directive to display the logo of network based on a series of numbers entered. However, I cannot get my HTML page to display anything. My project compiles, but the HTML page shows as blank. What did I do wrong?

Below is my code for the app.component.html:

<input type="text"[(ngModel)]="cardNumberInput"/>
<p>{{cardNumberInput}}</p>
<img applogo [cardType]="cardNumberInput" width="30"/>

Below is my code for app.module.ts:

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

import { FormsModule } from '@angular/forms'
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { LogoDirective } from './logo.directive';

@NgModule({
  declarations: [
    AppComponent,
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    FormsModule,
    LogoDirective
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

directive.ts:

import {Directive, Input, OnChanges, HostBinding} from '@angular/core';

enum CardType { VISA = 'visa', MASTERCARD = 'mastercard', AMERICAN_EXPRESS = 'aexpress', DISCOVER = 'discover', DINERS = 'diners', UNKNOWN = 'unknown'}

@Directive({
  selector: '[logo]'
})
export class LogoDirective implements OnChanges {


  @HostBinding('src')
  imageSource;

  @Input()
  cardNumber: string;

  ngOnChanges() {
    this.imageSource = 'assets/cards' + this.getCardTypeFromNumber() + '.png';
  }

  getCardTypeFromNumber(): CardType {
    if (this.cardNumber) {
      if (this.cardNumber.startsWith('34')) {
        return CardType.AMERICAN_EXPRESS;
      } else if (this.cardNumber.startsWith('4')) {
        return CardType.VISA;
      } else if (this.cardNumber.startsWith('5')) {
        return CardType.MASTERCARD;
      } else if (this.cardNumber.startsWith('60')) {
        return CardType.DISCOVER;
      } else if (this.cardNumber.startsWith('30')) {
        return CardType.DINERS;
      }
    }
    return CardType.UNKNOWN;
  }

}

directive.spec.ts:

import { LogoDirective } from './logo.directive';

describe('LogoDirective', () => {
  it('should create an instance', () => {
    const directive = new LogoDirective();
    expect(directive).toBeTruthy();
  });
});

There are couple of mistakes in your attribute binding. Please rectify your template as below:

  1. Your attribute selector name is logo not applogo
  2. Your attribute input name is cardNumber not cardType
  3. you are not specifying src attribute in image.

Changes Needed

  constructor(private element: ElementRef){
  }

  ngOnChanges() {
    debugger;
    this.imageSource = 'assets/cards' + this.getCardTypeFromNumber() + '.png';
    this.element.nativeElement.src = this.imageSource;
    this.element.nativeElement.alt = this.imageSource;
  }

<input type="text"[(ngModel)]="cardNumberInput"/>
<p>{{cardNumberInput}}</p>
<img logo [cardNumber]="cardNumberInput" width="30"  />

logo.directive.ts

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

enum CardType { VISA = 'visa', MASTERCARD = 'mastercard', AMERICAN_EXPRESS = 'aexpress', DISCOVER = 'discover', DINERS = 'diners', UNKNOWN = 'unknown'}

@Directive({
  selector: '[logo]'
})
export class LogoDirective implements OnChanges {
imageSource:string ='';

  @Input()
  cardNumber: string;
  constructor(private element: ElementRef){
  }

  ngOnChanges() {
    debugger;
    this.imageSource = 'assets/cards' + this.getCardTypeFromNumber() + '.png';
    this.element.nativeElement.src = this.imageSource;
    this.element.nativeElement.alt = this.imageSource;
  }

  getCardTypeFromNumber(): CardType {
    if (this.cardNumber) {
      if (this.cardNumber.startsWith('34')) {
        return CardType.AMERICAN_EXPRESS;
      } else if (this.cardNumber.startsWith('4')) {
        return CardType.VISA;
      } else if (this.cardNumber.startsWith('5')) {
        return CardType.MASTERCARD;
      } else if (this.cardNumber.startsWith('60')) {
        return CardType.DISCOVER;
      } else if (this.cardNumber.startsWith('30')) {
        return CardType.DINERS;
      }
    }
    return CardType.UNKNOWN;
  }
}

<input type="text"[(ngModel)]="cardNumberInput"/>
<p>{{cardNumberInput}}</p>
<img logo [cardNumber]="cardNumberInput" width="30"  />

you can see this working stackblitz - https://stackblitz.com/edit/angular-4bd23d It is showing the alt attributes as i don't have the images.

I hope it will help.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM