为什么在 Angular2 中使用变量的否定会破坏数据绑定?

Why does using the negation of a variable break data binding in Angular2?

这看起来应该是直截了当的,但我看不出我做错了什么。我有一个表单,可以根据 yes/no 单选按钮选择性地启用某些组件。我正在尝试根据该单选按钮后面的布尔值设置禁用属性。如果我将 [disabled] 设置为单选按钮,则一切正常(但与所需的行为相反)。如果我将 [disabled] 设置为布尔值的否定,它突然不起作用。我写了一个 Plunker 来说明:NegationConditionExample。只需删除 '!'来自 oResponded 变量,它将起作用,但与所需的行为相反。

代码如下:

//our root app component
import {Component, NgModule} from '@angular/core'
import {BrowserModule} from '@angular/platform-browser'
import { FormsModule } from '@angular/forms';
import { CommonModule }   from '@angular/common';

@Component({
  selector: 'my-app',
  template: `
    <form (ngSubmit)="onSubmit()" #resolveForm="ngForm">
      <div class="form-group">
        <label> Did anyone respond? </label>
        <div class="radio">
           <label>
              <input type="radio"
                     name="responded"
                     [(ngModel)]="oResponded"
                     #responded="ngModel"
                     value=true> Yes someone responded
          </label>
        </div>
        <div class="radio">
          <label>
              <input type="radio"
                     name="responded"
                     [(ngModel)]="oResponded"
                     #responded="ngModel"
                     value=false> No
          </label>
        </div>
      </div>
      <div class="form-group">
        <label for="responseType">What type of response?</label>
        <select class="form-control" id="responseType"
                required
                [(ngModel)]="oResponseType" name="responseType"
                #responseType="ngModel"
                [disabled]="!oResponded">
          <option *ngFor="let i of oResponseTypes" [value]="i">{{i}</option>
        </select>
        <div [hidden]="responseType.valid || responseType.pristine" class="alert alert-danger">
          Response Type is Required
        </div>
      </div>
      oResponded: {{oResponded}}
    </form>
  `,
})
export class App {
  oResponded: boolean;
  oResponseType: string;
  oResponseTypes: string[] = ["Agreed", "Disagreed", "Other"];
  constructor() {
    this.oResponded = false;
  }
}

@NgModule({
  imports: [ BrowserModule, FormsModule, CommonModule ],
  declarations: [ App ],
  bootstrap: [ App ]
})
export class AppModule {}`

因为改变单选按钮实际上是将oResponded的值设置为字符串类型,而不是布尔值。我在你的 oResponded: {{oResponded}} 下面添加了 === false: {{oResponded === "false"}},在那里你可以看到最初,oResponded 是一个布尔值(在构造函数中设置)但是切换单选按钮会将其切换为字符串值。

我想你可以通过评估字符串值来处理这个问题,或者创建一个方法将单选按钮的字符串值转换为布尔值。

我必须进行 2 处更改

  • value 周围添加 [] 以获得布尔值而不是字符串
          <input type="radio"
                 name="responded"
                 [(ngModel)]="oResponded"
                 #responded="ngModel"
                 [value]="true"> Yes someone responded
  • 将禁用的属性设置为属性而不是布尔值,并在 false 的情况下将其设置为 null:
    <select class="form-control" id="responseType"
            required
            [(ngModel)]="oResponseType" name="responseType"
            #responseType="ngModel"
            [attr.disabled]="oResponded ? null : true">

Plunker example