Angular 角度自定义下拉组件-选项更改时ngModel未正确更新
我试图创建一个实现ControlValueAccessor的自定义下拉组件,但我希望能够从父组件而不是自定义下拉列表中定义选项 理想情况下,我希望在我的选择中使用ngModel,在我的选项中使用ngValue来实现它,但由于某种原因,当我在选项中使用ngValue时,我的ngModel没有接收到与当前所选选项的ngValue关联的对象 下面是我试图实现的用法的简化示例: 注意:我知道在这种情况下,我可以只使用id字段并按自己的方式进行操作,但我有一些情况希望使用ngModel和ngValueAngular 角度自定义下拉组件-选项更改时ngModel未正确更新,angular,Angular,我试图创建一个实现ControlValueAccessor的自定义下拉组件,但我希望能够从父组件而不是自定义下拉列表中定义选项 理想情况下,我希望在我的选择中使用ngModel,在我的选项中使用ngValue来实现它,但由于某种原因,当我在选项中使用ngValue时,我的ngModel没有接收到与当前所选选项的ngValue关联的对象 下面是我试图实现的用法的简化示例: 注意:我知道在这种情况下,我可以只使用id字段并按自己的方式进行操作,但我有一些情况希望使用ngModel和ngValue
ID{{user.ID}-{{user.name}
在进行任何更改之前打印用户输出是一个用户对象,这是预期的。但是,只要我更改选项,selectedUser对象的值就是所选选项(即ID#…-…)的选项标记之间的字符串,而不是对象
如果我使用[value]=“user.id”
而不是[ngValue]=“user”
,那么一切都会按预期工作:
ID{{user.ID}-{{user.name}
如果我使用常规选择而不是自定义下拉列表
,则一切正常:
ID{{user.ID}-{{user.name}
以下是dropdown.ts和dropdown.html的实现: dropdown.html
下拉列表。ts
@组件({
选择器:“下拉列表”,
供应商:[
{
提供:NG_值访问器,
useExisting:forwardRef(()=>DropdownComponent),
多:真的
}
],
templateUrl:'./dropdown.component.html',
样式URL:['./dropdown.component.scss']
})
导出类DropdownComponent实现ControlValueAccessor{
私人内在价值:任何;
获取值():任意{
返回此.innerValue;
}
设置值(值:任意){
if(this.innerValue!==值){
this.innerValue=值;
这个。onChange(值);
}
}
writeValue(值:任意){
this.innerValue=值;
}
onChange=()=>{};
onTouched=()=>{};
registerChange(fn:(:any)=>void):void{this.onChange=fn;}
registerOnTouched(fn:()=>void):void{this.onTouched=fn;}
}
如果您希望看到完整的实现,我有一个简单的stackblitz设置:
我不确定我到底错了什么,非常感谢您的帮助。恐怕您不能在ng内容中使用html标记
,但您可以创建一个指令
@Directive(
{
selector:'[option]'
})
export class OptionDirective implements AfterViewInit{
@Input() ngValue:any;
innerHTML:string="";
constructor(private el:ElementRef)
{
}
ngAfterViewInit()
{
this.innerHTML=this.el.nativeElement.innerHTML
}
}
因此,您的.html变得像,请参见使用
ID{{user.ID}-{{user.name}
您的组件在一个div中包含ng内容,并且显示none
<select [ngClass]="[sizeClass]" [(ngModel)]="value">
<option *ngFor="let option of options" [ngValue]="option.ngValue">
{{option.innerHTML}}
</option>
</select>
<div [style.display]="'none'">
<ng-content></ng-content>
</div>
{{option.innerHTML}}
您可以使用ContentChildren获得选项和指令
@ContentChildren(OptionDirective) options:QueryList<OptionDirective>
@ContentChildren(OptionDirective)选项:QueryList
你可以从中看到
注意:我在同一个文件dropdown.component中加入了指令OptionDirective(您需要在模块中声明)
更新使用指令,我们可以将其用作指令“选项”的选择器
@指令(
{
选择器:'option'//
<select [ngClass]="[sizeClass]" [(ngModel)]="value">
<option *ngFor="let option of options" [ngValue]="option.ngValue">
{{option.innerHTML}}
</option>
</select>
<div [style.display]="'none'">
<ng-content></ng-content>
</div>
@ContentChildren(OptionDirective) options:QueryList<OptionDirective>
@Directive(
{
selector:'option' //<--use 'option'
})
export class OptionDirective implements AfterViewInit{
...
}
<dropdown [(ngModel)]="selectedUser" (ngModelChange)="onUserChange($event)">
<option *ngFor="let user of users;" [ngValue]="user">
ID#{{user.id}} - {{user.name}}
</option>
</dropdown>