【问题标题】:Ternary operator within [ngValue]; dynamically deselecting select value[ngValue] 内的三元运算符;动态取消选择值
【发布时间】:2016-12-08 22:04:37
【问题描述】:

如果用户从另一个下拉列表更改他们的选择(这也会隐藏有问题的选择输入),我想从表单上的选择输入中清除值(反应式)。理想情况下,我想能够在模板中内联执行此操作,而不是向控制器添加代码。我的一个想法是尝试在绑定我的选项的 [ngValue] 上使用三元运算符。

上下文代码:

<form [formGroup]="myForm">
<div>
    <label for="constrainingDropdown">Constraining Dropdown</label>
    <div>
        <select name="constrainingDropdown" formControlName="constrainingDropdown">
            <option disabled value="">Select an Option</option>
            <option *ngFor="let opt of constraints" [ngValue]="opt.code">{{opt.value}}</option>
        </select>
    </div>
    <div [hidden]="myForm.controls.constrainingDropdown.value !== 'OPT1'">
       <div> 
            <select name="constrainingDropdown" formControlName="myDropdown">
                <option disabled value="">Select an Option</option>
   RELEVANT ==> <option *ngFor="let myOpt of options" [ngValue]="{myForm.controls.constrainingDropdown.value !== 'OPT1' ? '' : myOpt.code}">{{myOpt.value}}</option>
            </select>
        </div>
    </div>
</div>
</form>

这会导致某种模板解析错误:是否可以在 ngValue 中使用三元运算符?还是我需要另一种解决方案?同样,不要为这个简单的逻辑在控制器中编写代码。

当前方法:订阅表单更改事件

this.myForm.controls['constrainingDropdown'].valueChanges.subscribe (
    (opt: string) => {
        if(opt === 'OPT1') {
           this.myForm.controls.myDropdown.patchValue('');
        }
    }
)

【问题讨论】:

  • 你能不能把[ngValue]="{myForm.controls.constrainingDropdown.value !== 'OPT1' ? '' : myOpt.code}"改成[value]="myForm.controls.constrainingDropdown.value !== 'OPT1' ? '' : myOpt.code"
  • 我从未见过[ngValue] 在野外被使用,我不确定你为什么要用花括号将值括起来

标签: angular ternary-operator angular2-forms


【解决方案1】:

直接回答你的问题:确实可以在模板中使用三元

我怀疑你的模板语法是否正确。以下内容应该适合您:

改变 [ngValue]="{myForm.controls.constrainingDropdown.value !== 'OPT1' ? '' : myOpt.code}"

[value]="myForm.controls.constrainingDropdown.value !== 'OPT1' ? '' : myOpt.code"。正如我之前所说的那样,您不应该将三元组括在大括号中。我以前从未见过[ngValue] 被使用过,正确的语法是[value]

【讨论】:

  • 您的答案在输入时对我来说效果很好,并且有信心是否也适用于 select 并且应该被标记为正确答案。
【解决方案2】:

你可以使用ngModel进行双向绑定,然后使用ngIf显示一些东西:

<form>
  <div *ngIf="id === 1">
    <select name="id" [(ngModel)]="id">
      <option *ngFor="let option of options" [ngValue]="option.code">
        {{option.code}}
      </option>
    </select>
  </div>

  <div *ngIf="id === 2">
    <select name="id" [(ngModel)]="id">
      <option *ngFor="let option of options" [ngValue]="option.code">
        {{option.code}}
      </option>
    </select>
  </div>
</form>

这是working Plunker

【讨论】:

  • 这并不能真正回答问题 - 假设您正在对两个选择进行建模(我是),ngIf 不会消除为第二个选择存储的值,即使它不再在 DOM 中。跨度>
  • 我不确定我是否理解您的问题。上面的示例可用于建模任意数量的选择。你有 Plunker 吗?
  • Plnkr。希望该链接有效。我希望在将第一个选择的选择从 2 更改为 1 时删除第二个选择的字符串值。
  • 您可以创建一个custom pipe 来过滤数组,但是如果不知道它的实际应用,就很难知道什么是您的情况的最佳解决方案。
【解决方案3】:

您发布的代码有一些奇怪的地方。我会尽量猜测你的意思。

首先要做的是,我们将纠正您模板中的错误,并通过删除双 ! 使逻辑更易于阅读,您的意思是 === 或您的意思是 !== 第二个!开头很混乱,可能会导致意外行为(假设选择 OPT1 时隐藏):

<div [hidden]="myForm.controls.constrainingDropdown.value === 'OPT1'">

然后,我们将根据您的示例和代码更新您的另一个下拉列表,其中 formControlName 似乎不正确,而是将名称设置为 myDropdown,我们还将在未选择事件 OPT1:

<select name="constrainingDropdown" formControlName="myDropdown">
   <option disabled value="">Select an Option</option>
   <option *ngFor="let myOpt of options" [ngValue]="myOpt.code">{{myOpt.value}}</option>
</select>

最后我们要订阅第一个选择的.valueChanges 并从那里驱动我们的自定义逻辑:

constructor(private _fb: FormBuilder) {
  this.myForm = _fb.group({
    constrainingDropdown: [''],
    myDropdown: ['']
  });

this.myForm.controls['constrainingDropdown']
  .valueChanges.subscribe(value => {
    if(value === 'OPT1') {
      this.myForm.controls['myDropdown'].setValue('');
      this.myForm.controls['myDropdown'].disable();
    } else {
      this.myForm.controls['myDropdown'].enable();
    }
  });
}

附录 - 如果我们想要做的只是删除第二个下拉列表的值从整体myForm.value 一个简单的disable() 控件上的所有是必需的,因为该值仅包括启用的控件' 值。

这是Reactive Forms Implementation

【讨论】:

  • 为代码中的错别字(额外的!;错误的 formControlName)道歉,这是漫长的一天的结束,我忽略了几件事。我希望能够在 HTML 中内联执行此操作,但我最终像您一样订阅了 valuechange。你能解释一下三元运算符在这里做什么吗?在我看来,它看起来是多余的。
  • 您的三元组是多余的,如果选择了 OPT1,则为所有可能的值分配 '',否则为实际值。假设它的存在是有原因的,我会在提供答案时采取最少接触的方法。
  • 假设它有效,它不会是多余的:这正是我想要的。问题是它不起作用。如果我为第一个下拉菜单选择了 OPT2,为第二个下拉菜单选择,然后在第一个下拉菜单中选择 OPT1,我对第二个下拉菜单的选择未设置为空字符串,正如我根据运算符所期望的那样。我将只订阅 valuechange,因为它的代码不多。
  • [ngValue]不会在选择中更改某些内容时更改控件的所选值并自身。我认为这就是您遇到断开连接的地方。
  • 是的,听起来那是我的困惑。期望 [ngValue] 更改 formControl 的值。
【解决方案4】:

在反应式表单中,您可以动态添加/删除控件。您可以初始化一次表单,然后根据您的要求添加/删除表单控件..

绑定formControlName 可以通过三元运算符完成,然后在打字稿中根据应用的条件添加/删除这些控件

例子:

                      USING REACTIVE FORMS IN ANGULAR

TEMPLATE ( HTML )

 <input [formControlName]=" condtion ? 'control1' : 'control2'" />


TYPE SCRIPT (TS)

myFormGroup:FormGroup

ngOnInit(){
this.initForm()
this.addControlsOnContionalBasis()
}

initForm() {
  this.myFormGroup= new FormGroup({
});


addControlsOnContionalBasis(){
if(condtion){
    this.myFormGroup.addControl('control1',FormControl(null,Validators.required));


}else{
    this.myFormGroup.addControl('control2',FormControl(null,Validators.required));

}
}

【讨论】:

  • 能否详细说明您的答案?
  • 在反应式表单中,您可以动态添加/删除控件,您可以初始化表单盎司,然后根据您的要求添加/删除表单控件。绑定 formControlName 可以通过三元运算符完成,然后在打字稿中添加/删除这些控件根据条件应用......谢谢
猜你喜欢
  • 1970-01-01
  • 2023-02-17
  • 1970-01-01
  • 2022-01-10
  • 2018-11-30
  • 1970-01-01
  • 1970-01-01
  • 2019-11-19
  • 2013-06-28
相关资源
最近更新 更多