【问题标题】:Mutually exclusive select with same options in Angular 4Angular 4中具有相同选项的互斥选择
【发布时间】:2018-06-20 21:30:47
【问题描述】:

我正在尝试实现 3 个选择下拉菜单,它们具有与选项相同的对象数组。所有 3 个下拉菜单都是互斥的,即如果我在一个下拉菜单中选择一个选项,则它不应显示在其他两个等中。这是我的代码:

home.component.html

<select formControlName="secQues1" id="securityQuestion1"
class="form-control">
    <option value="" disabled>Select your first security question...</option>
    <option *ngFor="let question of securityQuestions" [value]="question.index">
    {{question.name}}</option>
</select>

<select formControlName="secQues2" id="securityQuestion2"
class="form-control">
    <option value="" disabled>Select your first security question...</option>
    <option *ngFor="let question of securityQuestions" [value]="question.index">
    {{question.name}}</option>
</select>

<select formControlName="secQues3" id="securityQuestion3"
class="form-control">
    <option value="" disabled>Select your first security question...</option>
    <option *ngFor="let question of securityQuestions" [value]="question.index">
    {{question.name}}</option>
</select>

这是我的选项数组。这里大约有 15-20 个条目。

home.component.ts

securityQuestions = [{
    index : 0,
    name : "What was your childhood nickname?"
},{
    index : 1,
    name : "In what city did you meet your spouse/significant other?"
}]

我尝试使用 3 个不同的数组,然后从 2 个数组拼接,但是当有人更改选项时它不起作用(在这种情况下,旧选项应该添加回其他 2 个下拉菜单)。 有什么建议吗?

【问题讨论】:

  • 其他两个下拉列表反映了相同的值,因为您对所有 3 个都具有相同的 value 绑定。具体来说,它们都绑定到question.index 属性,因此每当此属性更改时,下拉值都会更改。您需要将value 属性绑定到不同的变量,以使它们独立。

标签: javascript angular filter ngfor


【解决方案1】:

我会按照 Octavian Mărculescu 的建议去做。三个不同的数组,仅根据下拉列表的选定值进行过滤。

  • 选择一个值
  • 选择TwoValue
  • 选择三值

我不确定您是否要使用 ngModel 来绑定选定的值,或者您是否会使用其他方法。

template.component.html

<select (change)="selectChange($event, 1)" formControlName="secQues1" id="securityQuestion1" class="form-control">
    <option value="" disabled>Select your first security question...</option>
    <option *ngFor="let question of securityQuestions1" [value]="question.index"> {{question.name}}</option>
</select>

<select (change)="selectChange($event, 2)" formControlName="secQues2" id="securityQuestion2" class="form-control">
    <option value="" disabled>Select your first security question...</option>
    <option *ngFor="let question of securityQuestions2" [value]="question.index">
    {{question.name}}</option>
</select>

<select (change)="selectChange($event, 3)" formControlName="secQues3" id="securityQuestion3" class="form-control">
    <option value="" disabled>Select your first security question...</option>
    <option *ngFor="let question of securityQuestions3" [value]="question.index">
    {{question.name}}</option>
</select>

component.ts

public selectOneValue;
public selectTwoValue;
public selectThreeValue;

public securityQuestions1 = []

public securityQuestions2 = []

public securityQuestions3 = []

constructor(private questionsService: QuestionsService){
 // get your questions promise or observable 

  this.securityQuestions1 = Object.assign([], securityQuestionsSource);
  this.securityQuestions2 = Object.assign([], securityQuestionsSource);
  this.securityQuestions3 = Object.assign([], securityQuestionsSource);
}

public selectChange($event, secQuestionArray: number) {

    if(secQuestionArray == 1){
        // filter 2 and 3
    } else  if (secQuestionArray == 2){
        // filter 1 and 3
    } else if(secQuestionArray == 3){
        // filter 1 and 2
    }
}

【讨论】:

  • 我试过了,但就像我说的,如果有人更改了选定的选项,旧的选项也会被过滤掉。
  • 您是否尝试克隆 sourceArray? this.securityQuestions1 = Object.assign([], securityQuestionsSourceArray);
【解决方案2】:

我会为您的question 模型添加另一个属性,即selectedIn。所以你会知道它已经在其他地方被选中了,它是哪个&lt;select&gt;

securityQuestions = [{
    index : 0,
    name : "What was your childhood nickname?",
    selectedIn : 2
},{
    index : 1,
    name : "In what city did you meet your spouse/significant other?",
    selectedIn : 1
}]

然后,如果已在其他地方选择了给定选项,您可以简单地隐藏它:

<select (change)="onSelectChange($event,1)">
    <option value="" disabled>Select your first security question...</option>
    <option *ngFor="let question of securityQuestions" [hidden]="question.selectedIn && !question.selectedIn==1" [value]="question.index" >
    {{question.name}}</option>
</select>

<select (change)="onSelectChange($event,2)">
    <option value="" disabled>Select your second security question...</option>
    <option *ngFor="let question of securityQuestions" [hidden]="question.selectedIn && !question.selectedIn==2" [value]="question.index" >
    {{question.name}}</option>
</select>

<select (change)="onSelectChange($event,3)">
    <option value="" disabled>Select your third security question...</option>
    <option *ngFor="let question of securityQuestions" [hidden]="question.selectedIn && !question.selectedIn==3" [value]="question.index" >
    {{question.name}}</option>
</select>

在您的组件中:

onSelectChange($event, selectIndex){
    let questionIndex = Number($event.target.value) // 2 == question.index

    // Now update the securityQuestions array
    securityQuestions = securityQuestions.map( question => {
        // delete previous selection if any
        if(question.selectedIn == selectIndex) delete question.selectedIn
        // Mark the current question as selected in <select> n°1
        if(question.index == questionIndex) question.selectedIn = selectIndex
        return question
    })
}

【讨论】:

  • 这对我不起作用。 hidden 属性只会在第一次而不是每次选择选项时检查,对吧?
  • 当然,你必须添加一些逻辑来定义selectedIn。使用$event.target.value。我还没有开发出完整的解决方案,但你明白了。
  • OK 我已经在组件中添加了代码,用于更新securityQuestions 数组。 (当然是未经测试的代码)
  • 我尝试了类似的方法,但它不起作用,因为隐藏指令可能只在第一次而不是每次更新数组时检查。
猜你喜欢
  • 2018-02-04
  • 1970-01-01
  • 1970-01-01
  • 2018-01-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-29
相关资源
最近更新 更多