你好我在这个问题上被封了几天
我向你解释我有一个输入或我根据某些条件应用一条消息但是我有另一个条件,如果它是一个多线文本使用textarea如果它是内联使用输入
当我在输入中设置条件* ngIf =“!multiline”时出现问题我收到错误消息:
无法读取未完成的属性“错误”
我已经应用了一些东西,我已经在div中封装了我的输入,包括我的条件,因此我添加了myModel&& myModel.error以便初始化对象
没有效果
如果有人有我感兴趣的解决方案
这是我的代码:
import {
ChangeDetectionStrategy,
ChangeDetectorRef,
Component,
ElementRef,
forwardRef,
Input,
OnInit,
ViewChild
} from '@angular/core'
import {
ControlValueAccessor,
NG_VALUE_ACCESSOR
} from '@angular/forms'
@Component({
selector: 'mae-input',
templateUrl: './input.html',
changeDetection: ChangeDetectionStrategy.OnPush,
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => InputComponent),
multi: true
}
],
host: {
class: 'input-form'
}
})
export class InputComponent implements OnInit, ControlValueAccessor {
@Input() theme: string = 'material' // 'material' or 'block' or 'inline'
@Input() minlength: number
@Input() maxlength: number
@Input() min: number
@Input() max: number
@Input() pattern: string
// tslint:disable-next-line:no-reserved-keywords
@Input() type: string
@Input() autocomplete: string
@Input() required
@Input() disabled
@Input() readonly
@Input() multiline: boolean
@Input() withCharCount: boolean
@Input() label: string
@Input() name: string
@Input() placeholder: string
@Input() help: string
@Input() hint: string
@Input() bg: string
@Input() color: string
@Input() borderColor: string
@Input() labelColor: string
@Input() myModel: any
ValidationHints = {
required: ' Please fill out this field.',
minlength: ' Field must be at least 3 characters long.',
maxlength: ' Field cannot be more than 24 characters long.',
pattern: ' Please match the requested format.'
}
focus: boolean = false
@ViewChild('inputField')
private _inputField: ElementRef
@ViewChild('inputFieldMultiline')
private _inputFieldMultiline: ElementRef
private _model: string
constructor(private cd: ChangeDetectorRef) {
}
// tslint:disable-next-line:no-empty
onChange: any = () => {
}
// tslint:disable-next-line:no-empty
onTouched: any = () => {
}
ngOnInit() {
this.required = this.required !== undefined && this.required !== false
this.disabled = this.disabled !== undefined && this.disabled !== false
this.readonly = this.readonly !== undefined && this.readonly !== false
this.myModel = ''
}
get model() {
return this._model
}
set model(val: string) {
if (val === this._model) {
return
}
this._model = val
this.onChange(val)
}
writeValue(value: any) {
this._model = value
this.cd.markForCheck()
}
registerOnChange(fn: any): void {
this.onChange = fn
}
registerOnTouched(fn: any): void {
this.onTouched = fn
}
onFocus() {
if (this.readonly || this.disabled) {
return
}
this.focus = true
}
onBlur() {
if (this.readonly || this.disabled) {
return
}
this.focus = false
this.onTouched()
}
_focusInputField() {
if(!this.readonly && !this.disabled) {
if (this.multiline) {
this._inputFieldMultiline.nativeElement.focus()
} else {
this._inputField.nativeElement.focus()
}
}
}
}
<div *ngIf="!multiline">
<input
#inputField
class="input-container__input"
*ngIf="!multiline"
(focus)="onFocus()"
(blur)="onBlur()"
placeholder="{{placeholder}}"
name="{{name}}"
type="{{type || 'text'}}"
pattern="{{pattern}}"
minlength="{{minlength}}"
maxlength="{{maxlength}}"
min="{{min}}"
max="{{max}}"
[required]="required"
autocomplete="{{autocomplete}}"
[disabled]="disabled"
[readonly]="readonly"
[(ngModel)]="model"
#myModel="ngModel"
/>
</div>
<ng-container *ngTemplateOutlet="inputContent"></ng-container>
<div *ngIf="multiline" class="input-container__multiline">
<div class="input-container__input input-container__multiline__place-holder">{{model}}</div>
<textarea
#inputFieldMultiline
class="input-container__input input-container__multiline__input"
[(ngModel)]="model"
(focus)="onFocus()"
(blur)="onBlur()"
placeholder="{{placeholder}}"
name="{{name}}"
minlength="{{minlength}}"
maxlength="{{maxlength}}"
[required]="required"
[disabled]="disabled"
[readonly]="readonly"
#myModel="ngModel"
></textarea>
</div>
</div>
<ng-container *ngTemplateOutlet="inputContent"></ng-container>
{{hint}}
</div>
<ng-template #inputContent>
<div class="input-container__hints" *ngIf="this.theme !== 'inline'">
<div class="input-container__hints--left">
<div *ngIf="myModel && myModel.errors && myModel.touched" class="alert-error">
<div [hidden]="!myModel.errors.required">
<i class="mi mi-warning"></i>
{{ValidationHints.required}}
</div>
<div [hidden]="!myModel.errors.minlength">
<i class="mi mi-warning"></i>
{{ValidationHints.minlength}}
</div>
<div [hidden]="!myModel.errors.maxlength">
<i class="mi mi-warning"></i>
{{ValidationHints.maxlength}}
</div>
<div [hidden]="!myModel.errors.pattern">
<i class="mi mi-warning"></i>
{{ValidationHints.pattern}}
</div>
</div>
</div>
<div class="input-container__hints--right" *ngIf="withCharCount">
{{(model?.length || 0) + (maxlength ? ('/' + maxlength) : '')}}
</div>
</div>
</ng-template>
答案 0 :(得分:0)
请注意,您已将multiline
定义为@Input()
,这意味着您将multiline
从另一个组件传递到InputComponent
。
只要从父组件注入或更新OnChanges
的值,就使用生命周期钩子multiline
来检测更改。像这样修改你的代码 -
添加此导入语句:
import {OnChanges, SimpleChanges} from '@angular/core';
将此行添加到InputComponent
:
export class InputComponent implements OnInit, ControlValueAccesso, OnChanges {
// other code goes here
public multiline: boolean = false; <--- define an initial value
ngOnChanges(changes:SimpleChanges){
if('multiline' in changes){ <---- detect changes and update
this.multiline = changes['multiline'].currentValue;
}
}
}
如果要为使用@Input()
定义的其他属性设置类似的错误,请考虑为它们实现上述模式。
希望它有所帮助。