Angular 2 动态更改选择的单选按钮

4

编辑

我想要一个单选按钮组,其中选择一个单选按钮会选择另一个单选按钮;“点击的”(未选中的)单选按钮永远不会被选择,因为试图选择它(通过单击它),其默认行为是“点击”的单选按钮会变为“选中”。类似于这个 Angular 2 演示

但是这个演示并不完全符合我的要求,因为它在选择另一个单选按钮时有延迟。

这里是使用 jQuery 的演示。 这没有延迟,单击单选按钮永远不会勾选该单选按钮。例如,单击第二个单选按钮永远不会选择第二个单选按钮。要选择第二个单选按钮,您需要单击第一个单选按钮。


旧版:我尝试使用 Angular 2 实现以下功能:我有三个单选按钮 A、B 和 C,其中 A 和 B 中的两个可以被选择,当选择第三个单选按钮 C 时,它应该选择 B。因此,C 在视觉上永远不会被选择,或仅在瞬间被选择。

我无法使其正常工作。因此,我认为重新创建更简单的问题可能是一个好主意,所以我正在尝试解决这个更容易的问题。我可以使选择 A 选择 B,选择 B 选择 C,选择 C 选择 A。

A 是第一个单选按钮,B 是第二个,C 是第三个单选按钮。

onRadioChange(val) {
    val = val == 2 ? 0 : ++val;
    this.radio_val=val;
}

这里是 plunker 演示

然而,正如您在演示中所看到的那样,它仅适用于第一次点击。因此,点击 B 将选择 C,但再次点击 B 将选择 B。

我认为这是主要问题。

上述演示使用了 [(ngModel)],但对 [checked] 也是一样的。

这里是带有 checked 的演示

但是,使用 setTimeout 和 [(ngModel)] 可以解决这个问题

这就是我想做的,但没有延迟

这与 Angular2 的生命周期钩子有关吗?

请帮忙解决。


请重新表述你的问题,你在演示中提到的A、B是什么? - Aravind
@Aravind 你好。它们中没有一个是 A 或 B。这是一个新的演示,当你点击“A”,也就是第一个单选按钮时,它会选择第二个单选按钮。选择第二个单选按钮会选择第三个按钮。选择第三个按钮会选择第一个单选按钮。 - user3290525
现在发生了什么? - Aravind
@Aravind 我提供了3个演示。我希望它能像最后一个演示那样工作。点击单选按钮会选择另一个单选按钮。但是最后一个演示并不完全符合我的要求。我不希望在选择其他单选按钮时有延迟。我提供的其他演示都无法正常工作,因为点击相同的单选按钮会选择已选中的单选按钮。 - user3290525
5个回答

3

点击事件:为单选按钮设置模型值。 改变事件:调用点击事件,以便改变事件将重写模型值。

<input type='radio' name='test' [value]='0' [(ngModel)]='radio_val' (change)='onRadioChange(0) '(click)='onRadioClick(0)'>
<input type='radio' name='test' [value]='1' [(ngModel)]='radio_val' (change)='onRadioChange(1) (click)='onRadioClick(1)'>
<input type='radio' name='test' [value]='2' [(ngModel)]='radio_val' (change)='onRadioChange(2) (click)='onRadioClick(2)'>

更新:

在Angular2的生命周期中,单选按钮的change事件在click事件之后。对于我们想要的内容,我们必须使用settimeout让Angular2重新渲染视图以响应change事件。

这里是plunker演示


第一次单击单选按钮可以,但第二次不行,就像我的演示一样... - user3290525
@user3290525 很有趣,第二次不起作用。第三次又可以了。我会调查一下的。 - Pengyy
谢谢!我希望有一个非常简单的解决方案,就像我提供的使用jQuery的工作演示一样。 - user3290525
@user3290525 我已经更新了我的答案。在Angular2的生命周期钩子中,单选按钮的更改事件似乎是在点击事件之后触发的。此外,我们必须使用setTimeout来让Angular2重新渲染视图以响应更改事件。 - Pengyy
我不知道更改事件是在点击事件之后发生的。我从这个链接中错过了什么吗?你能否在你的回答中添加它? - user3290525
1
@user3290525 抱歉,我尝试了一下,但没有找到任何关于这个的参考资料。对我来说,我是在尝试解决你的问题时发现的。和其他人交流后,他们告诉我这很正常... 你可以在我提供的 plunker 上添加 console.log 来确认这一点。 - Pengyy

2
我认为你需要在 (click) 上进行操作。在 (change) 上无法处理所有情况,因为当单击选定的按钮时不会发生任何更改,因此不会触发更改事件。我还将使用 boolean 控制哪个是 [checked],因为这被证明更容易。所以尝试使用 (click)='onRadioChange(...)' 而不是 (change),并添加 [checked]='checked[...]' 与必要的代码将按钮绑定到 checked:boolean[];工作示例:我在每次单击时都进行了更改。

1
这对你应该有效:

这应该适用于您:

onRadioChange(val) {
  this.radio_val = (this.radio_val+1) %3;
}

不要使用change事件,而应该挂接到click事件。

演示


很确定他们不希望被点击的那个不被选中。 - ChiefTwoPencils
你能换个说法吗...那是一个双重否定。 - pixelbits
翻译:糟糕,应该这样:相当确定他们不希望选择被单击的那个。不确定现在他们实际想要什么。 - ChiefTwoPencils
我现在明白了 :) 我想那就是我做的... 当你点击一个单选按钮时,它并没有被选中 - 它选择的是旁边的一个。 - pixelbits
尝试点击第一个三次...我尝试了但放弃了,然后将“checked”绑定到布尔值。 - ChiefTwoPencils

0
      // html
       <ion-card *ngFor="let val of addressList;">
                    <ion-card-content (click)='onSelectionChange(val)'>
                        <ion-row>
                            <ion-col size="2">
                                <input type="checkbox" class="selectBox" [checked]="val._id === selectedEntry._id"  [value]="val._id"  (change)='onSelectionChange(val)' >
                            </ion-col>
                            <ion-col size="8">
                                {{val.area}} ,{{val.city}}<br>
                                {{val.nearBy}}<br>
                                {{val.city}} , {{val.state}} ,{{val.pincode}},
                                {{val.country}}
                            </ion-col>
                        </ion-row>
                    </ion-card-content>
                </ion-card>

    // component
         public addressList: any;
        public selectedEntry: any = {
            _id: ""
          }

  ngOnInit() {
    this.getAddress();
  }

  getAddress() {
    this._ProductService.getAddress(localStorage.getItem('userId')).subscribe((data: any) => {
      this.addressList = data;
      console.log(this.addressList)
    });
  }


         onSelectionChange(entry) {
            this.selectedEntry = Object.assign({}, this.selectedEntry, entry);
            console.log(this.selectedEntry, "select")

          }

0
我指的是 Angular 2 文档:生命周期钩子
根据文档,

Angular 的单向数据流规则禁止在视图组合后更新视图。这两个钩子都会在组件的视图组合后触发。

然后
// Wait a tick because the component's view has already been checked
this.logger.tick_then(() => this.comment = c);

所以这个演示毫秒参数设置为0。但是不像这个jQuery演示那样跳过设置单选按钮为“选中”。


我想我有点困惑,你的jQuery示例允许一个已经选中的单选按钮保持选中状态,但是你说点击的那个单选按钮永远不应该被选中。我的回答是否符合你的要求? - ChiefTwoPencils
@ChiefTwoPencils 如果我的表述让人困惑,我会重新表述成这样:“在jQuery演示中,例如点击第二个单选按钮将永远不会选择第二个单选按钮。” 所以,在我的jQuery示例中,当您选择第二个单选按钮时,无论点击多少次,第三个单选按钮都会保持选中状态。要选择第二个单选按钮,请选择第一个单选按钮。但是我的问题是,当我点击第二个单选按钮时,它会选择第三个按钮。再次点击第二个单选按钮时,它会选择第二个单选按钮。 - user3290525
我认为你可以稍微修改一下我的代码,就能让它适用于你的需求。我的代码会在两个未被点击的选项之间切换,而你需要让它保持在一个选项上。如果你遇到问题,我可能晚些时候有时间来编辑它。 - ChiefTwoPencils
@ChiefTwoPencils 我认为我通过阅读 Angular 2 指南中的“生命周期钩子”文章找到了解决方案。使用 setTimeout 函数,并将第二个参数设置为 '0'。将第一个演示的 setTimeout 的第二个参数设置好似可以解决该问题。它的工作方式不完全像 jQuery,因为有一瞬间单击后的选中状态会出现一下,在 jQuery 中,你甚至不会看到表示选中所点击的单选框上的黑点。 - user3290525
1
我认为这对你的方法是正确的,但属性绑定的处理方式不同。我想我在我的答案中对***plunkr*** 进行了一些编辑,但现在它已经正确了。请试一试。它可以做到你想要的(还有更多),而且没有任何延迟或setTimeout - ChiefTwoPencils
我不知道down vote是干什么用的。setTimeout( ..., 0)是Angular2让你做的,因为Angular有这个“1周期”(1 cycle)。我没有接受ChiefTwoPencils的答案,因为我不需要点击单选按钮来改变其他单选按钮,这也不是我想要的。 - user3290525

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接