Mention提及
提及组件。
何时使用
用于在输入中提及某人或某事,常用于发布、聊天或评论功能。
单独引入此组件
想要了解更多关于单独引入组件的内容,可以在快速上手页面进行查看。
import { NzMentionModule } from 'ng-zorro-antd/mention';
代码演示
基本使用
import { Component, ViewEncapsulation } from '@angular/core';
@Component({
selector: 'nz-demo-mention-basic',
encapsulation: ViewEncapsulation.None,
template: `
<nz-mention [nzSuggestions]="suggestions" (nzOnSelect)="onSelect($event)">
<input
placeholder="input here"
nzMentionTrigger
nz-input
[(ngModel)]="inputValue"
(ngModelChange)="onChange($event)"
/>
</nz-mention>
`
})
export class NzDemoMentionBasicComponent {
inputValue: string = '@afc163';
suggestions = ['afc163', 'benjycui', 'yiminghe', 'RaoHai', '中文', 'にほんご'];
onChange(value: string): void {
console.log(value);
}
onSelect(suggestion: string): void {
console.log(`onSelect ${suggestion}`);
}
}
匹配内容列表为异步返回时。
import { Component, ViewEncapsulation } from '@angular/core';
import { MentionOnSearchTypes } from 'ng-zorro-antd/mention';
@Component({
selector: 'nz-demo-mention-async',
encapsulation: ViewEncapsulation.None,
template: `
<nz-mention [nzSuggestions]="suggestions" [nzLoading]="loading" (nzOnSearchChange)="onSearchChange($event)">
<input nzMentionTrigger nz-input [(ngModel)]="inputValue" />
</nz-mention>
`
})
export class NzDemoMentionAsyncComponent {
inputValue: string;
loading = false;
suggestions: string[] = [];
onSearchChange({ value }: MentionOnSearchTypes): void {
console.log(`search: ${value}`);
this.loading = true;
this.fetchSuggestions(value, suggestions => {
console.log(suggestions);
this.suggestions = suggestions;
this.loading = false;
});
}
fetchSuggestions(value: string, callback: (suggestions: string[]) => void): void {
const users = ['afc163', 'benjycui', 'yiminghe', 'jljsj33', 'dqaria', 'RaoHai'];
setTimeout(() => {
return callback(users.filter(item => item.indexOf(value) !== -1));
}, 500);
}
}
自定义建议(含头像)
注意,nzSuggestions
不为 string[]
时,需要提供 valueWith
。
import { Component, ViewEncapsulation } from '@angular/core';
@Component({
selector: 'nz-demo-mention-avatar',
encapsulation: ViewEncapsulation.None,
template: `
<nz-mention [nzSuggestions]="webFrameworks" [nzValueWith]="valueWith" (nzOnSelect)="onSelect($event)">
<input nz-input nzMentionTrigger [(ngModel)]="inputValue" />
<ng-container *nzMentionSuggestion="let framework">
<nz-avatar nzSize="small" [nzText]="framework.name" [nzSrc]="framework.icon"></nz-avatar>
<span>{{ framework.name }} - {{ framework.type }}</span>
</ng-container>
</nz-mention>
`,
styles: [
`
.ant-avatar.ant-avatar-sm {
width: 14px;
height: 14px;
margin-right: 8px;
position: relative;
}
`
]
})
export class NzDemoMentionAvatarComponent {
inputValue: string;
webFrameworks = [
{ name: 'React', type: 'JavaScript', icon: 'https://zos.alipayobjects.com/rmsportal/LFIeMPzdLcLnEUe.svg' },
{ name: 'Angular', type: 'JavaScript', icon: 'https://zos.alipayobjects.com/rmsportal/PJTbxSvzYWjDZnJ.png' },
{ name: 'Dva', type: 'Javascript', icon: 'https://zos.alipayobjects.com/rmsportal/EYPwSeEJKxDtVxI.png' },
{ name: 'Flask', type: 'Python', icon: 'https://zos.alipayobjects.com/rmsportal/xaypBUijfnpAlXE.png' }
];
valueWith = (data: { name: string; type: string; icon: string }) => data.name;
onSelect(value: string): void {
console.log(value);
}
}
多行模式。
import { Component, ViewEncapsulation } from '@angular/core';
@Component({
selector: 'nz-demo-mention-multilines',
encapsulation: ViewEncapsulation.None,
template: `
<nz-mention [nzSuggestions]="suggestions">
<textarea nz-input [nzAutosize]="{ minRows: 4, maxRows: 4 }" [(ngModel)]="inputValue" nzMentionTrigger>
</textarea>
</nz-mention>
`
})
export class NzDemoMentionMultilinesComponent {
inputValue: string;
suggestions = ['afc163', 'benjycui', 'yiminghe', 'RaoHai', '中文', 'にほんご'];
}
通过 nzPrefix
属性自定义触发字符。默认为 @
, 可以定义为数组。
import { Component, ViewEncapsulation } from '@angular/core';
import { MentionOnSearchTypes } from 'ng-zorro-antd/mention';
@Component({
selector: 'nz-demo-mention-multiple-trigger',
encapsulation: ViewEncapsulation.None,
template: `
<nz-mention [nzSuggestions]="suggestions" (nzOnSearchChange)="onSearchChange($event)" [nzPrefix]="['#', '@']">
<input
placeholder="input @ to mention people, # to mention tag"
nzMentionTrigger
nz-input
[(ngModel)]="inputValue"
/>
</nz-mention>
`
})
export class NzDemoMentionMultipleTriggerComponent {
inputValue: string;
suggestions: string[] = [];
users = ['afc163', 'benjycui', 'yiminghe', 'RaoHai', '中文', 'にほんご'];
tags = ['1.0', '2.0', '3.0'];
onSearchChange({ value, prefix }: MentionOnSearchTypes): void {
console.log('nzOnSearchChange', value, prefix);
this.suggestions = prefix === '@' ? this.users : this.tags;
}
}
向上展开建议。
import { Component, ViewEncapsulation } from '@angular/core';
@Component({
selector: 'nz-demo-mention-placement',
encapsulation: ViewEncapsulation.None,
template: `
<nz-mention nzPlacement="top" [nzSuggestions]="suggestions" (nzOnSelect)="onSelect($event)">
<input nzMentionTrigger nz-input [(ngModel)]="inputValue" (ngModelChange)="onChange($event)" />
</nz-mention>
`
})
export class NzDemoMentionPlacementComponent {
inputValue: string;
suggestions = ['afc163', 'benjycui', 'yiminghe', 'RaoHai', '中文', 'にほんご'];
onChange(value: string): void {
console.log(value);
}
onSelect(suggestion: string): void {
console.log(`onSelect ${suggestion}`);
}
}
自定义建议
注意,nzSuggestions
不为 string[]
时,需要提供 valueWith
。
import { Component, ViewEncapsulation } from '@angular/core';
@Component({
selector: 'nz-demo-mention-custom-tag',
encapsulation: ViewEncapsulation.None,
template: `
<nz-mention [nzSuggestions]="webFrameworks" [nzValueWith]="valueWith" (nzOnSelect)="onSelect($event)">
<input placeholder="@someone" nz-input nzMentionTrigger [(ngModel)]="inputValue" />
<ng-container *nzMentionSuggestion="let framework">
<span>{{ framework.name }} - {{ framework.type }}</span>
</ng-container>
</nz-mention>
`
})
export class NzDemoMentionCustomTagComponent {
inputValue: string;
webFrameworks = [
{ name: 'React', type: 'JavaScript' },
{ name: 'Angular', type: 'JavaScript' },
{ name: 'Laravel', type: 'PHP' },
{ name: 'Flask', type: 'Python' },
{ name: 'Django', type: 'Python' }
];
valueWith = (data: { name: string; type: string }) => data.name;
onSelect(value: string): void {
console.log(value);
}
}
受控模式,例如配合 Form 使用。
import { Component, OnInit, ViewChild, ViewEncapsulation } from '@angular/core';
import { AbstractControl, FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
@Component({
selector: 'nz-demo-mention-controlled',
encapsulation: ViewEncapsulation.None,
template: `
<form nz-form [formGroup]="validateForm" (ngSubmit)="submitForm()">
<nz-form-item>
<nz-form-label [nzSm]="6" nzFor="mention">Top coders</nz-form-label>
<nz-form-control [nzSm]="16" nzErrorTip="More than one must be selected!">
<nz-mention #mentions [nzSuggestions]="suggestions">
<input id="mention" placeholder="input here" formControlName="mention" nzMentionTrigger nz-input />
</nz-mention>
</nz-form-control>
</nz-form-item>
<nz-form-item nz-row style="margin-bottom:8px;">
<nz-form-control [nzSpan]="14" [nzOffset]="6">
<button type="button" nz-button nzType="primary" (click)="submitForm()">Submit</button>
<button type="button" nz-button (click)="resetForm()">Reset</button>
</nz-form-control>
</nz-form-item>
</form>
`
})
export class NzDemoMentionControlledComponent implements OnInit {
suggestions = ['afc163', 'benjycui', 'yiminghe', 'RaoHai', '中文', 'にほんご'];
validateForm: FormGroup;
@ViewChild('mentions', { static: true }) mentionChild: any;
get mention(): AbstractControl {
return this.validateForm.get('mention')!;
}
constructor(private fb: FormBuilder) {}
ngOnInit(): void {
this.validateForm = this.fb.group({
mention: ['@afc163 ', [Validators.required, this.mentionValidator]]
});
}
mentionValidator = (control: FormControl): { [s: string]: boolean } => {
if (!control.value) {
return { required: true };
} else if (this.mentionChild.getMentions().length < 2) {
return { confirm: true, error: true };
}
return {};
};
submitForm(): void {
this.mention.markAsDirty();
this.mention.updateValueAndValidity();
if (this.mention.valid) {
console.log('Submit!!!', this.mention.value);
console.log(this.mentionChild.getMentions());
} else {
console.log('Errors in form!!!');
}
}
resetForm(): void {
this.validateForm.reset({
mention: '@afc163 '
});
}
}
通过 disabled
属性设置是否生效。通过 readOnly
属性设置是否只读。
import { Component, ViewEncapsulation } from '@angular/core';
@Component({
selector: 'nz-demo-mention-readonly',
encapsulation: ViewEncapsulation.None,
template: `
<nz-mention [nzSuggestions]="suggestions">
<input
style="margin-bottom: 10px"
placeholder="this is disabled Mention"
nzMentionTrigger
nz-input
disabled
[(ngModel)]="inputValue"
/>
<input placeholder="this is readOnly Mention" nzMentionTrigger nz-input readOnly [(ngModel)]="inputValue" />
</nz-mention>
`
})
export class NzDemoMentionReadonlyComponent {
inputValue: string;
suggestions = ['afc163', 'benjycui', 'yiminghe', 'RaoHai', '中文', 'にほんご'];
}
渲染提及
import { Component, ViewEncapsulation } from '@angular/core';
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
@Component({
selector: 'nz-demo-mention-preview',
encapsulation: ViewEncapsulation.None,
template: `
<nz-tabset>
<nz-tab nzTitle="Write">
<nz-mention [nzSuggestions]="suggestions">
<textarea
nz-input
[nzAutosize]="{ minRows: 4, maxRows: 4 }"
[(ngModel)]="inputValue"
(ngModelChange)="renderPreView()"
nzMentionTrigger
>
</textarea>
</nz-mention>
</nz-tab>
<nz-tab nzTitle="Preview">
<pre [innerHTML]="preview"></pre>
</nz-tab>
</nz-tabset>
`
})
export class NzDemoMentionPreviewComponent {
inputValue: string = 'Switch tab view preview @NG-ZORRO ';
preview: SafeHtml;
suggestions = ['NG-ZORRO', 'angular', 'Reactive-Extensions'];
constructor(private sanitizer: DomSanitizer) {
this.renderPreView();
}
getRegExp(prefix: string | string[]): RegExp {
const prefixArray = Array.isArray(prefix) ? prefix : [prefix];
let prefixToken = prefixArray.join('').replace(/(\$|\^)/g, '\\$1');
if (prefixArray.length > 1) {
prefixToken = `[${prefixToken}]`;
}
return new RegExp(`(\\s|^)(${prefixToken})[^\\s]*`, 'g');
}
renderPreView(): void {
if (this.inputValue) {
const regex = this.getRegExp('@');
const previewValue = this.inputValue.replace(
regex,
match => `<a target="_blank" href="https://github.com/${match.trim().substring(1)}">${match}</a>`
);
this.preview = this.sanitizer.bypassSecurityTrustHtml(previewValue);
}
}
}
API
<nz-mention [nzSuggestions]="suggestions">
<textarea
nz-input
[(ngModel)]="value"
nzMentionTrigger>
</textarea>
</nz-mention>
nz-mentioncomponent
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
[nzMentionTrigger] | 用于指定提及的触发元素 (必须) | HTMLTextAreaElement | HTMLInputElement | - |
[nzMentionSuggestion] | 自定义建议渲染模板 | TemplateRef<any> | - |
[nzLoading] | 加载中 | boolean | false |
[nzNotFoundContent] | 未找到时的内容 | string | '无匹配结果,轻敲空格完成输入' |
[nzPlacement] | 建议框位置 | 'button' | 'top' | 'bottom' |
[nzPrefix] | 触发弹出下拉框的字符 | string | string[] | '@' |
[nzSuggestions] | 建议内容 | any[] | [] |
[nzValueWith] | 建议选项的取值方法 | (any) => string | (value: string) => string | |
(nzOnSelect) | 下拉框选择建议时回调 | EventEmitter<any> | - |
(nzOnSearchChange) | 输入框中 @ 变化时回调 | EventEmitter<MentionOnSearchTypes> | - |
方法
方法名 | 说明 |
---|---|
getMentions | 获取 input[nzMentionTrigger] 中的提及数组 |
nzMentionTrigger
用于指定提及的触发元素
<nz-mention>
<textarea nzMentionTrigger></textarea>
</nz-mention>
<nz-mention>
<input nzMentionTrigger>
</nz-mention>
nzMentionSuggestion
自定义建议渲染模板
<nz-mention
[nzSuggestions]="items"
[nzValueWith]="valueWith">
<input nz-input nzMentionTrigger>
<ng-container *nzMentionSuggestion="let item">
<span>{{ item.label }} - {{ item.value }}</span>
</ng-container>
</nz-mention>
MentionOnSearchTypes
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
value | 搜索关键词 | string | - |
prefix | 触发前缀 | string | - |