我有两个组成部分:
<app-google-login-button></app-social-login-button>
<app-facebook-login-button></app-facebook-login-button>
app-facebook-login-button
看起来像这样:
<button type="button" class="btn btn-label btn-facebook" (click)="facebookSignIn()"
*ngIf="!(isMobile | async)?.matches">
<label>
<fa-icon [icon]="['fab', 'facebook']" size="xs"></fa-icon>
</label> Sign in with Facebook
</button>
<button type="button" class="btn btn-label btn-facebook" (click)="mobileFacebookSignIn()"
*ngIf="(isMobile | async)?.matches">
<label>
<fa-icon [icon]="['fab', 'facebook']" size="xs"></fa-icon>
</label> Sign in with Facebook
</button>
app-google-login-button
看起来像这样:
<button type="button" class="btn btn-label btn-google" (click)="googleSignIn()" *ngIf="!(isMobile | async)?.matches">
<label>
<fa-icon [icon]="['fab', 'google']" size="xs"></fa-icon>
</label> Sign in with Google
</button>
<button type="button" class="btn btn-label btn-google" (click)="mobileGoogleSignIn()" *ngIf="(isMobile | async)?.matches">
<label>
<fa-icon [icon]="['fab', 'google']" size="xs"></fa-icon>
</label> Sign in with Google
</button>
我想将两者结合起来并使用通用的app-social-login-button
。该组件的外观如何?
答案 0 :(得分:2)
通过提供的HTML
代码,我可以给您一些建议。
创建一个包含社交媒体列表的ENUM
。 (这将限制可以传递给组件的社交媒体的价值)
使用app-social-login-button
参数作为Enum值为@Input
创建一个组件(Google或Facebook)。
在组件SocialLoginButtonComponent
中,检查传递的值,并使HTML
类似:
<button type="button" class="btn btn-label btn-facebook" (click)="SignIn()"
*ngIf="!(isMobile | async)?.matches">
<label>
<fa-icon [icon]="iconArray" size="xs"></fa-icon>
</label> Sign in with {{companyName}}
</button>
<button type="button" class="btn btn-label btn-facebook" (click)="SignInWithMobile()"
*ngIf="(isMobile | async)?.matches">
<label>
<fa-icon [icon]="iconArray" size="xs"></fa-icon>
</label> Sign in with {{companyName}}
</button>
在组件中,检查@Input
参数并设置companyName
,iconArray
相应地配置SignIn()
和SignInWithMobile()
以调用相应公司的API。
MediaService
来处理SignIn
的API调用,具体取决于Company Name
。尽量不要将所有逻辑放在组件本身中。答案 1 :(得分:2)
定义一个接口,该接口声明可配置的选项,但还包括单击按钮时的回调函数。如果您不想为每个按钮注入回调,那么另一种方法是定义一个字符串令牌,例如“ facebook”,并将该值传递给共享服务。
export interface SocialButton {
// button text
title: string;
// Font Awesome icon
icon: any;
// CSS class for the button
btn: string;
// make mobile just a condition of the click
click: (mobile: boolean) => void;
}
然后可以将上述接口的对象作为参数传递给组件。
@Component({
selector: 'app-social-login-button',
template: `
<button type="button"
[ngClass]="getClass()"
(click)="click()">
<label>
<fa-icon [icon]="options.icon" size="xs"></fa-icon>
</label> Sign in with {{options.title}}
</button>`,
changeDetection: ChangeDetectionStrategy.OnPush
})
export class SocialLoginButtonComponent {
@Input()
public options: SocialButton;
public isMobile: Observable<any>;
public getClass() {
return {
'btn': true,
'btn-label': true,
[this.options.btn]: true
};
}
public click() {
this.isMobile
.pipe(first())
.subscribe(value => this.options.click(value));
}
}
您可以定义一个共享服务,该服务将创建SocialButton
选项作为数组。
@Injectable()
export class SocialButtonService {
public buttons(): SocialButton[] {
return [this.faceBook(), this.google()];
}
public faceBook(): SocialButton {
return {title: 'Facebook', icon: ['fab', 'facebook'], btn: 'btb-facebook', click: (m) => this.signIn('facebook', m)}
}
public google(): SocialButton {
return {title: 'Google', icon: ['fab', 'google'], btn: 'btb-google', click: (m) => this.signIn('google', m)}
}
public signIn(platform: string, mobile: boolean) {
// do work
}
}
您现在可以轻松地在另一个组件中显示所有按钮。
@Component({
template: `
<app-social-login-button *ngFor="let option of options" [options]="option"></app-social-login-button>
`
})
export class SocialLoginButtonsComponent {
public options: SocialButton[];
public constructor(service: SocialButtonService) {
this.options = service.buttons();
}
}