【问题标题】:Angular2 Reactive Form Model Binding - Multi Select not reflecting updatesAngular2 Reactive Form Model Binding - 多选不反映更新
【发布时间】:2017-09-26 00:09:55
【问题描述】:

我有一个非常复杂的表单,到目前为止设置起来很痛苦。我在这里走到尽头,遇到了一些麻烦。

我正在使用一个名为ng-select 的多选插件。该指令采用两个数据数组,[items][active]。 Items 是可能的选项列表, active 是默认选择的值。

我正在尝试使用我的反应式表单模型进行配置。

<span>
    <ng-select formControlName="AttributeValue" [allowClear]="true" [multiple]="true" [items]="fetchSourceList()" [active]="formatValues(ruleAttributeData.AttributeValue)" placeholder="Click to Select a Value" class="inlineSelect"></ng-select>
</span> 

这是我的表单到目前为止的样子:

底部看到的array 是我的模型在创建表单时包含的内容。这些是选定的值。

用于填充active(默认选中)的方法如下所示:

export interface ValueData {
    RuleDetailID?: number;
    AttrValue: string;
    Value: string;
    IsValueRetired: boolean;
}

private formatValues(data) {
    return data.map((data: ValueData) => {
        return { id: data.AttrValue, text: data.Value };
    });
}

我的fetchSourceList() 方法只返回一个可供选择的可能项目数组。当调用下拉菜单选择一个新选项时,我没有看到已经选择的选项,这是一件好事。这让我觉得模型绑定最初可以工作,但之后会在某个地方中断,

到目前为止,页面加载正常,我的默认选中项在 UI 中标记为选中,form 的值按预期显示了数组中的 8 个项。

问题来了..

虽然我的[items]="fetchSourceList()" 包含尚未选择的数据列表,但选择一个选项不会将其添加到输入中。

当我从可用选项中选择输入时,选择输入未显示已添加。当我获得表单的值时,我看到该项目已添加到选定项目的数组中,并带有一个捕获。如果我继续从列表中选择选项,它始终是我选择的最后一个以数字结尾的选项我的阵列中有 8 个。

其次,如果我从 ui 上的这个多选中删除一个项目,它不会删除。

因此,这里似乎有一些模型问题没有按预期工作。

我做错了什么?

【问题讨论】:

  • 对此我不太确定,但你能检查一下 formatValues() 方法是否真的有效吗? ,它被定义为私有方法,您正试图从 DOM 访问它。
  • @priteshagrawal - 它正在工作,刚刚确认。 ruleAttributeData.AttributeValue 是我通过接口传递的一个对象,以便专门为多选设置它的格式。数据需要格式化为具有textid 键的对象数组。在这种情况下,如果方法不起作用,它们将显示为 undefined
  • @priteshagrawal 然而,它似乎确实多次调用该方法,似乎每个数组值一个。如果我的数组包含 10 个选择表单的选项,formatValues 方法将被调用 10 次。看起来很奇怪...
  • 好的@SBS,你可以试试双向绑定吗? .我从来没有使用过 ng-select ,但是我使用了其他一些 UI 库,其中做一些类似的事情,比如 [(active)] = "formatValues(ruleAttributeData.AttributeValue)" 和 [ngModelOptions]="{standalone: true }"
  • 在使用响应式表单时我该怎么做?

标签: angular typescript


【解决方案1】:

根据docs(请参阅该页面中的文档链接),ng-select 似乎没有itemsactive 作为其Input 属性。要指定选项列表,您需要使用options 属性。要选择 active 选项,请将其设置为组件内 formControl 的默认值。

allowClear 属性仅用于单选(而非多选)。

此外,您的 options 数组元素应符合文档中的这种类型,

interface IOption {
    value: string;
    label: string;
    disabled?: boolean; // this is optional
}

您可以将此接口导入为,

import { IOption } from 'ng-select';

假设,在您的示例中,您的每个 option 元素都包含像 { id: "172", text: "Account Manager" } 这样的值,其中 id 是要存储的实际 valuetext 是要显示的 label,我们必须使'options'的数组符合这样的IOptions接口(省略disabled属性,因为它是'可选'),

组件

import { IOption } from 'ng-select';

form: FormGroup;
// choose the 'active' or default selections for the options dropdown
// by including the corresponding 'value' property of IOptions list elements
// returned from the getOptions() call. Use it as the formControl's initial value (array since it is multi-select)
defaultSelections = ['172', '180', '113']; 

ngOnInit() {
 this.form = new FormGroup({
  AttributeValue: new FormControl(this.defaultSelections)
 });
}

getOptions(data): Array<IOption> {
    return data.map((data: ValueData) => {
        return { value: data.AttrValue, label: data.Value };
    });
}

模板

<form novalidate [formGroup]="form">
 <span>
  <ng-select formControlName="AttributeValue" [multiple]="true" [options]="getOptions(ruleAttributeData.AttributeValue)" placeholder="Click to Select a Value" class="inlineSelect">
  </ng-select>
 </span>
</form>

我自己没有尝试过这个(以前从未与ng-select 合作过),但我从文档和那里给出的示例中非常确信它会起作用。您可能必须将组件中使用的变量/方法调整为您希望它适用于您的特定用例的方式。希望对您有所帮助。

【讨论】:

    猜你喜欢
    • 2015-09-07
    • 2017-11-10
    • 2017-09-22
    • 1970-01-01
    • 2016-03-26
    • 2017-02-28
    • 1970-01-01
    • 2020-12-19
    • 1970-01-01
    相关资源
    最近更新 更多