从模板切换Angular 2+的自举单选按钮

时间:2018-02-08 22:31:31

标签: angular twitter-bootstrap

我正在尝试使用angular class和attribute语句切换一组单选按钮。当我单击按钮时,我可以看到根据需要添加和删除了active类,并且也设置了checked属性。但是,单选按钮实际上并没有被检查。

<div class="btn-group " data-toggle="buttons">
  <label class="btn btn-primary" [ngClass]="{'active': s}">
    <input type="radio" name="options" id="option1" autocomplete="off" (click)="s=true" [attr.checked]="s"> Yes
  </label>
  <label class="btn btn-primary" [ngClass]="{'active': !s}">
    <input type="radio" name="options" id="option2" autocomplete="off"(click)="s=false" [attr.checked]="!s"> No
  </label>
</div>

Live demo of the problem

使用Angular 5,bootstrap 4.0.0

编辑:不重复,因为我知道还有其他方法可以做到这一点。但我想弄清楚为什么上述方法不起作用。

EDIT2:如果我绑定到(click)="doSomething()"的函数,它就可以了!但也会导致错误,因为函数没有定义。如果我创建该功能,它将再次停止工作。

3 个答案:

答案 0 :(得分:1)

处理click事件时会发生奇怪的事情。如果直接在模板中设置标志值,则不会正确检查单选按钮:

(click)="s = false"

但是如果使用方法设置标志,那么一切都运行良好:

(click)="setValue(false)"

您可能更愿意处理change事件,这似乎始终为work correctly

(change)="s = false"

更好的选择是使用ngModel数据绑定,如this stackblitz所示:

<div class="btn-group" data-toggle="buttons">
  <label class="btn btn-primary" [class.active]="s">
    <input type="radio" name="options" id="option1" [(ngModel)]="s" [value]="true"> Yes
  </label>
  <label class="btn btn-primary" [class.active]="!s">
    <input type="radio" name="options" id="option2" [(ngModel)]="s" [value]="false"> No
  </label>
</div>

答案 1 :(得分:1)

我有更好的解决方案。你可能会欣赏这种简约。因为用户实际上要单击单选按钮,所以他们使用ngmodel将数据传递到字段中,这是您不想要的。

HTML

<div class="btn-group" role="group" aria-label="View Type">
   <button type="button" [class.active]="sortClass" (click)="switch(1)" class="btn btn-secondary">
      <span>Grid</span>
   </button>
   <button type="button" [class.active]="listClass" (click)="switch(2)" class="btn btn-secondary">
      <span>List</span>
   </button>
 </div>

component.ts

// Create variables
private sortClass: boolean;
private listClass: boolean;

// INITIALIZE TRUE / FALSE for both variables
constructor() {
    this.sortClass = false;
    this.listClass = true;
}

switch(i) {
        if (i === 1) {
            this.sortClass = !this.sortClass
            this.listClass = !this.listClass
        } else {
            this.listClass = !this.listClass
            this.sortClass = !this.sortClass
        }
    }

然后你会看到一个活跃,另一个假。当您单击它们时,它们将替换为true / false。

答案 2 :(得分:0)

更改属性必须在Angular的上下文之外进行,因此您需要NgZone.run()

https://angular.io/api/core/NgZone

&#13;
&#13;
blah() {
    this.zone.run(() => { console.log("boom!"); });
}
&#13;
<div class="btn-group " data-toggle="buttons">
  <label class="btn btn-primary" [ngClass]="{'active': s}">
    <input type="radio" name="options" id="option1" autocomplete="off" (click)="s=true; blah();" [attr.checked]="s === 'true' ? true : false"> Yes
  </label>
  <label class="btn btn-primary" [ngClass]="{'active': !s}">
    <input type="radio" name="options" id="option2" autocomplete="off"(click)="s=false; blah();" [attr.checked]="s === 'false' ? true : false"> No
  </label>
</div>
&#13;
&#13;
&#13;