typescript 将 Select2 集成到 Angular2 应用程序中

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/36173678/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 03:22:00  来源:igfitidea点击:

Integrate Select2 into the Angular2 app

jqueryangulartypescriptjquery-select2

提问by Radoslav Stoyanov

I'm trying to integrate Select2into the Angular2app I'm building. I managed to get select2running and my multiple selects are transformed as expected. My problem now is how am I supposed to get the selected values and which event should I use for the binding. I tried binding (change)event on the select element but nothing happened. Maybe I should use some other event on the created by the plugin select2-containerelement?
The select2plugin is integrated following thisanswer.
Anybody tried similar mix? Is it possible to get it work or I have to switch to ng2-selectdirective instead?

我正在尝试集成Select2Angular2我正在构建的应用程序中。我设法开始select2运行,并且我的多个选择按预期进行了转换。我现在的问题是我应该如何获取选定的值以及我应该使用哪个事件进行绑定。我尝试(change)在 select 元素上绑定事件,但什么也没发生。也许我应该在由插件select2-container元素创建的对象上使用其他一些事件?
select2插件是按照答案集成的。
有人试过类似的组合吗?是否有可能让它工作,或者我必须切换到ng2-select指令?

Update
Bonus question :) - Even if I give up select2and use standard multiple select, how should I get its value? I tried binding it to a property with [(ngModel)]="_selectedValues"but it remains empty when I select any option. Is the multiple checkbox the only way for multiple choice?

更新
奖励问题 :) - 即使我放弃select2并使用标准多选,我应该如何获得它的价值?我尝试将它绑定到一个属性,[(ngModel)]="_selectedValues"但是当我选择任何选项时它仍然是空的。多选框是多选的唯一方式吗?

Update 2
For the bonus question - the workaround I found was to use one way event binding like (change)="selectedValues=$event.target.selectedOptions". Then I added a setterfor the selectedValuesproperty like this:

更新 2
对于奖金问题 - 我发现的解决方法是使用一种方式事件绑定,如(change)="selectedValues=$event.target.selectedOptions". 然后我setter为这样的selectedValues属性添加了一个:

public set selectedValues(value: Array<any>) {
    this._selectedValues.length = 0;
    for(let v of value){
        this._selectedValues.push(v.value);
    }
};

回答by Radoslav Stoyanov

The only working solution for the select2I found, is getting the value with jQuery in the ngAfterViewInitmethod like this:

select2我发现的唯一可行的解​​决方案是在如下ngAfterViewInit方法中使用 jQuery 获取值:

jQuery('.fields-select').on(
        'change',
        (e) => this._selectedValues = jQuery(e.target).val()
);

So my final code looks like this:

所以我的最终代码如下所示:

import {Component, AfterViewInit} from 'angular2/core';

@Component({
    selector: 'filters',
    templateUrl: 'template.html'
})
export class FiltersComponent implements AfterViewInit {

    private _availableFields: Array<any> = ['Value1', 'Value2', 'Value3','Value4'];
    private _selectedFields: Array<string> = [];

    ngAfterViewInit(){
        jQuery('.fields-select').select2();
        jQuery('.fields-select').on(
            'change',
            (e) => this._selectedFields = jQuery(e.target).val()
        );
    };
}

And in the template:

在模板中:

<select id="fields" class="form-control fields-select" multiple="multiple">
    <option *ngFor="#field of _availableFields" [value]="field">{{field}}</option>
</select>

Hope this will save someone's life some day :)

希望有一天这会挽救某人的生命:)

回答by S.Galarneau

I've made my own implementation of it, with options, value, and available items as Input params of my component. This is my first version of it, it could be very flexible and augmented pretty easily.

我自己实现了它,将选项、值和可用项目作为组件的输入参数。这是我的第一个版本,它可以非常灵活并且很容易扩充。

import { Component, ElementRef, Input, Output, AfterViewInit, EventEmitter, ViewChild } from '@angular/core';
declare var $: any;

@Component({
    selector: 'custom-select',
    template: `<select #select class="form-control"></select>`
})

export class CustomSelectComponent implements AfterViewInit {
    @ViewChild('select') private select: ElementRef;
    @Input() items: any[];
    @Input() options: any = {};
    @Input() value: any;
    @Output() valueChange = new EventEmitter<string[]>();

    constructor() { }

    ngAfterViewInit() {
        let selectElement = $(this.select.nativeElement);

        if (this.isMultiple()) {
            selectElement.attr('multiple', true);
        }

        selectElement.select2({
            data: $.map(this.items, (obj: any) => {
                let item = {
                    id: this.options.identifier ?  obj[this.options.identifier] : obj.id,
                    text: this.options.name ? obj[this.options.name] : obj.name
                };

                if ($.trim(item.id) === '') { console.warn(`No 'id' value has been set for :`, obj); }
                if ($.trim(item.text) === '') { console.warn(`No 'name' value has been set for :`, obj); }

                return item;
            })
        });
        $(selectElement).val(this.value).trigger('change');

        selectElement.on('change', (e: any) => {
            this.valueChange.emit($(e.target).val());
        });

    };

    private isMultiple() {
        return !!(this.options && this.options.multiple === true);
    }
}

And you can call it like that

你可以这样称呼它

<custom-select [items]="array" [options]="{multiple:true}" (valueChange)="update($event)" [value]="valueVar"></custom-select>