@Input未更新内容儿童(自定义广播按钮)
我目前正在创建自定义无线电组组件。我想确保开发人员可以按照他们想要的方式定义按钮,因此我使用@contentChildren
的内容投影,以便最终看起来像这样:
<custom-radio-group>
<custom-radio *ngFor="let radio of radios"></custom-radio>
</custom-radio-group>
我试图做到这一点,以便父收音机组组件确保name
属性在其所有无线电按钮子女中都是相同的。 这样做是为了避免开发人员试图在同一无线电组的无线电按钮上应用不同名称的情况(因为我也想让无线电按钮可能存在于广播组之外),例如以下示例:
<custom-radio-group>
<custom-radio [name]="'a'">Option 1</custom-radio>
<custom-radio [name]="'b'">Option 2</custom-radio>
<custom-radio [name]="'c'">Option 3</custom-radio>
<custom-radio [name]="'d'">Option 4</custom-radio>
</custom-radio-group>
对于上面的示例,我想强制所有广播按钮上应用最后一个单选按钮的名称的规则。
在我的无线电组组件中,我有以下代码:
export class CustoRadioGroupComponent implements AfterContentInit {
@ContentChildren(CustomRadioComponent) radioButtons!: QueryList<CustomRadioComponent>
name!: string;
ngAfterContentInit(): void {
if (this.radioButtons) {
this.updateRadioButtonNames();
}
}
/**
* Ensure integrity of the group name
* Any dev may try to apply different names to the buttons of a group
* Make sure that only the last name is propagated
*/
updateRadioButtonNames() {
this.name = this.radioButtons.last.name;
this.radioButtons.forEach((radio, index, radioButtons) => {
if (index !== radioButtons.length - 1) {
radio.name = this.name;
radio._markForCheck();
}
});
}
}
对于广播按钮本身,
@Component({
selector: 'custom-radio',
styleUrls: ['./custom-radio.component.scss'],
templateUrl: './custom-radio.component.html',
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush
}) export class CustomRadioComponent {
/** Name attribute of the input radio */
@Input() name!: string;
constructor(private changeDetectorRef: ChangeDetectorRef) {}
_markForCheck() {
// console.log(this.name); ---> prints "d" 3 times, as expected
this.changeDetectorRef.markForCheck();
}
...
}
---------------------------------------------------------------------------------
custom-radio.component.ts
....
<input type="radio" [name]="name" ...>
....
我当前面临的问题是,即使我成功地更新了无线电按钮的name
属性从亲本无线电组组件中,这些更改并未反映在DOM中,如下所示:
< img src =“ https://i.sstatic.net/ujgbr.png” alt =“在此处输入图像说明”>
我知道name
正在更新,但我可以' t使其反射在DOM中。我在这里想念什么?
我怀疑可能有些可能的原因是:
ngafterContentinit
可以在无线电按钮初始化之前调用钩子;- 更改检测可能无法检测到对象属性更改(在
Radio.Name = this.name
中),而仅仅仅一个对象身份更改。
I'm currently in the process of creating a custom radio group component. I want to make sure that a developer can define the buttons the way they want, so I'm using content projection with @ContentChildren
so it can look something like this in the end:
<custom-radio-group>
<custom-radio *ngFor="let radio of radios"></custom-radio>
</custom-radio-group>
At the moment I am trying to make it so the parent radio group component ensures that the name
attribute is the same across all its radio button children.
This is done in order to avoid the scenario where a developer tries to apply different names to the radio buttons of the same radio group (since I also want to make it possible for radio buttons to exist outside of a radio group), like the following example:
<custom-radio-group>
<custom-radio [name]="'a'">Option 1</custom-radio>
<custom-radio [name]="'b'">Option 2</custom-radio>
<custom-radio [name]="'c'">Option 3</custom-radio>
<custom-radio [name]="'d'">Option 4</custom-radio>
</custom-radio-group>
For the example above, I want to force the rule where the name of the last radio button is applied across all radio buttons.
In my radio group component I have the following code:
export class CustoRadioGroupComponent implements AfterContentInit {
@ContentChildren(CustomRadioComponent) radioButtons!: QueryList<CustomRadioComponent>
name!: string;
ngAfterContentInit(): void {
if (this.radioButtons) {
this.updateRadioButtonNames();
}
}
/**
* Ensure integrity of the group name
* Any dev may try to apply different names to the buttons of a group
* Make sure that only the last name is propagated
*/
updateRadioButtonNames() {
this.name = this.radioButtons.last.name;
this.radioButtons.forEach((radio, index, radioButtons) => {
if (index !== radioButtons.length - 1) {
radio.name = this.name;
radio._markForCheck();
}
});
}
}
And for the radio button itself, I have:
@Component({
selector: 'custom-radio',
styleUrls: ['./custom-radio.component.scss'],
templateUrl: './custom-radio.component.html',
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush
}) export class CustomRadioComponent {
/** Name attribute of the input radio */
@Input() name!: string;
constructor(private changeDetectorRef: ChangeDetectorRef) {}
_markForCheck() {
// console.log(this.name); ---> prints "d" 3 times, as expected
this.changeDetectorRef.markForCheck();
}
...
}
---------------------------------------------------------------------------------
custom-radio.component.ts
....
<input type="radio" [name]="name" ...>
....
The issue I'm facing currently is that even though I am successfully updating the name
property of the radio buttons from the parent radio group component, these changes are not being reflected in the DOM, as you can see below:
I know the name
is being updated, but I can't make it reflect in the DOM. What am I missing here?
I suspect some possible causes might be:
ngAfterContentInit
hook might be called before the initialisation of the radio buttons;- Change detection might not detect an object property change (in
radio.name = this.name
), but instead only an object identity change.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论