@ViewChild 注释 returns 的用法在我的代码中未定义
usage of @ViewChild annotation returns undefined in my code
我有一个 angular 2 UI 。我在我的组件模板中定义了一个文本区域,我试图使用 @ViewChild 注释获取对该文本区域的引用。但是它正在返回 undefined 。我知道原因,但不知道如何解决此问题。问题出在
所以这是我在组件中的文本区域 html
<textarea id="messageTxt" formControlName="message" rows="6" [placeholder]="'PLACEHOLDERS.MESSAGE' | translate" #messageTxt></textarea>
所以我从我的组件 ts 文件中粘贴了部分代码,如下所示。
messageTextArea 结果是未定义的。我想这是因为 ngOnInit 方法,我们正在等待创建表单,直到我们得到服务的响应。知道如何重写代码以便在 messageTextArea 变量中获得正确的引用。
export class SmsTemplateFormComponent implements OnInit,AfterViewInit {
@ViewChild('messageTxt') messageTextArea: ElementRef;
constructor(
private fb: FormBuilder,
private templatesService: TemplatesService,
private configService: ConfigService,
private accountService: AccountsService
) {}
ngAfterViewInit() {
fromEvent(this.messageTextArea.nativeElement,'keyup').pipe(
map( (e: KeyboardEvent) => (e.target as HTMLTextAreaElement).value),
debounceTime(10),
distinctUntilChanged(),
switchMap( (value) => this.templatesService.retrieveSmsSegmentCount(value) )
).subscribe(
response => {
this.segmentCount = response.segmentCount;
}
);
}
ngOnInit() {
this.isFormLoading = true;
this.accountService.get(this.account.id).subscribe(
(value) => {
this.account = value;
this.isFormLoading = false;
this.messagePrefix = value.messagePrefix;
this.formGroup = this.fb.group(
{
defaultTemplate: [this.defaultInitialValue],
language: [null, Validators.required],
message: [ this.messagePrefix ? this.messagePrefix:'', [Validators.required]],
longUrl: ['']
},
{
validator: [
hasUrlTagValidator(TemplatesService.urlTag),
messagePrefixSMSValidator(this.messagePrefix? this.messagePrefix: null, 'message')
]
}
);
combineLatest(
this.messageControl.valueChanges,
this.urlControl.valueChanges
).subscribe(([message, url]) => {
const { html, length } = this.templatesService.compileSmsTemplate(
message,
url ? this.placeholderUrl : ''
);
this.messageHtml = html;
this.messageLength = length;
});
if (this.template) {
this.formGroup.setValue({
defaultTemplate: this.template.defaultTemplate,
language: this.template.language,
message: this.template.text,
longUrl: this.template.longUrl
});
}
this.urlControl.valueChanges.subscribe(() => {
const messageValue: string = this.messageControl.value;
if (!messageValue || !messageValue.includes(TemplatesService.urlTag)) {
this.messageControl.setValue(messageValue + TemplatesService.urlTag);
}
});
this.templatesService.retrieveSmsSegmentCount(this.messageControl.value)
.subscribe( response => {
this.segmentCount = response.segmentCount;
});
}
);
}
}
在您的情况下,您并不需要 fromEvent
。您可以将 keyup
事件绑定到您的文本区域:
<textarea id="messageTxt" formControlName="message" rows="6" [placeholder]="'PLACEHOLDERS.MESSAGE' | translate" (keyup)="doStuff(messageTxt.value)" #messageTxt></textarea>
然后在你的组件中:
doStuff(value: string) {
// do whatever with the value
}
我有一个 angular 2 UI 。我在我的组件模板中定义了一个文本区域,我试图使用 @ViewChild 注释获取对该文本区域的引用。但是它正在返回 undefined 。我知道原因,但不知道如何解决此问题。问题出在
所以这是我在组件中的文本区域 html
<textarea id="messageTxt" formControlName="message" rows="6" [placeholder]="'PLACEHOLDERS.MESSAGE' | translate" #messageTxt></textarea>
所以我从我的组件 ts 文件中粘贴了部分代码,如下所示。 messageTextArea 结果是未定义的。我想这是因为 ngOnInit 方法,我们正在等待创建表单,直到我们得到服务的响应。知道如何重写代码以便在 messageTextArea 变量中获得正确的引用。
export class SmsTemplateFormComponent implements OnInit,AfterViewInit {
@ViewChild('messageTxt') messageTextArea: ElementRef;
constructor(
private fb: FormBuilder,
private templatesService: TemplatesService,
private configService: ConfigService,
private accountService: AccountsService
) {}
ngAfterViewInit() {
fromEvent(this.messageTextArea.nativeElement,'keyup').pipe(
map( (e: KeyboardEvent) => (e.target as HTMLTextAreaElement).value),
debounceTime(10),
distinctUntilChanged(),
switchMap( (value) => this.templatesService.retrieveSmsSegmentCount(value) )
).subscribe(
response => {
this.segmentCount = response.segmentCount;
}
);
}
ngOnInit() {
this.isFormLoading = true;
this.accountService.get(this.account.id).subscribe(
(value) => {
this.account = value;
this.isFormLoading = false;
this.messagePrefix = value.messagePrefix;
this.formGroup = this.fb.group(
{
defaultTemplate: [this.defaultInitialValue],
language: [null, Validators.required],
message: [ this.messagePrefix ? this.messagePrefix:'', [Validators.required]],
longUrl: ['']
},
{
validator: [
hasUrlTagValidator(TemplatesService.urlTag),
messagePrefixSMSValidator(this.messagePrefix? this.messagePrefix: null, 'message')
]
}
);
combineLatest(
this.messageControl.valueChanges,
this.urlControl.valueChanges
).subscribe(([message, url]) => {
const { html, length } = this.templatesService.compileSmsTemplate(
message,
url ? this.placeholderUrl : ''
);
this.messageHtml = html;
this.messageLength = length;
});
if (this.template) {
this.formGroup.setValue({
defaultTemplate: this.template.defaultTemplate,
language: this.template.language,
message: this.template.text,
longUrl: this.template.longUrl
});
}
this.urlControl.valueChanges.subscribe(() => {
const messageValue: string = this.messageControl.value;
if (!messageValue || !messageValue.includes(TemplatesService.urlTag)) {
this.messageControl.setValue(messageValue + TemplatesService.urlTag);
}
});
this.templatesService.retrieveSmsSegmentCount(this.messageControl.value)
.subscribe( response => {
this.segmentCount = response.segmentCount;
});
}
);
}
}
在您的情况下,您并不需要 fromEvent
。您可以将 keyup
事件绑定到您的文本区域:
<textarea id="messageTxt" formControlName="message" rows="6" [placeholder]="'PLACEHOLDERS.MESSAGE' | translate" (keyup)="doStuff(messageTxt.value)" #messageTxt></textarea>
然后在你的组件中:
doStuff(value: string) {
// do whatever with the value
}