网站搜索

angular - 在 ng2-select2 指令中绑定响应式表单的 formControlName


我在我的 Angular 5 项目中使用响应式表单来处理表单。在该表单中,我使用 ng2-select2 创建 select2 下拉菜单,但当我尝试将 formControlName 绑定到我的 <select2></select2> 指令时,它出现了错误

错误 错误:没有用于名称为 'citizenship_id' 的表单控件的值访问器

这是我在 .ts 文件中的 ngOnInit 函数:

ngOnInit() {
    this.jobId = this.route.snapshot.queryParams.jobId;
    this.detailForm = new FormGroup({
        date_of_birth: new FormControl(null, Validators.required),
        gender: new FormControl('', Validators.required),
        marital_status: new FormControl('', Validators.required),
        npwp_family_status_id: new FormControl('', Validators.required),
        citizenship_id: new FormControl('', Validators.required),
    });

    this.ajaxOptions = {
        url: API_URL + '/generate-json',
        dataType: 'json',
        delay: 250,
        data: function (params) {
            return {
                s: params.term,
                page: params.page,
                model_name: 'country'
            };
        },
        type: 'POST',
        processResults: function (res) {
            let data = $.map(res.results, function (obj) {
                if (obj.overwriteId)
                    obj.id = obj.overwriteId;
                return obj;
            });

            return {
                results: data,
                pagination: res.pagination
            };
        }
    };

    this.options = {
        ajax: this.ajaxOptions,
        // theme: 'bootstrap',
        width: '100%',
        allowClear: true,
        placeholder: 'Select...',
        language: {
            'errorLoading': function () {
                return 'Searching…';
            }
        },
        templateResult: function (data) {
            return data.create === true ? data.text + ' <b style="color: lightgreen;">(create new)</b>' : data.text;
        },
        templateSelection: function (data) {
            return data.create === true ? data.text + ' <b class="text-success">(create new)</b>' : data.text;
        },
        escapeMarkup: function (markup) {
            return markup;
        },
        createTag: function (params) {
            var term = $.trim(params.term);
            return term ? {
                id: term,
                text: term,
                create: true
            } : null;
        },
        insertTag: function (data, tag) {
            var found = false;
            $.each(data, function (i, e) {
                if (e.text.toLowerCase() == tag.text.toLowerCase())
                    found = true;
            });
            if (!found)
                data.unshift(tag);
        },
        minimumInputLength: 2
    };
}

这是我的 .html 文件:

<select2 [options]="options" formControlName="citizenship_id"></select2>

答案#1

虽然 Select2 本身不支持 ReactiveForms,但这里有一个不错的解决方法:

创建一个新的隐藏输入并绑定到 formControlName。每当 select2 的值发生变化时,也更新隐藏输入的值。

如果您从 API 获取响应并且想要预先选择值,请使用一个包含响应中选定值的数组变量(例如:[{id: 1, text: 'Selected Value'}]),然后在 select2 指令中,设置 [value]="{selected_value_id}"。

感谢原帖作者 @DennyRustandi 和 @SunilSingh 在评论中提供的信息。

答案#2

问题出在你的自定义组件 select2。看起来你的组件没有实现 ControlValueAccessor。只需确保你的组件确实实现了 ControlValueAccessor。

查看简单示例 - https://stackblitz.com/edit/angular-custom-from-control-hqpwgb

参考这篇不错的文章 - https://alligator.io/angular/custom-form-control/