将 Select2 集成到 Angular2 应用程序中

Posted

技术标签:

【中文标题】将 Select2 集成到 Angular2 应用程序中【英文标题】:Integrate Select2 into the Angular2 app 【发布时间】:2016-07-10 11:29:26 【问题描述】:

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

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

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

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

【问题讨论】:

至于 ng2-select,我发现它到目前为止还太不成熟,无法用于除真正基本用例之外的任何用途。 【参考方案1】:

我找到的select2 唯一可行的解​​决方案是在ngAfterViewInit 方法中使用jQuery 获取值,如下所示:

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

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

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()
        );
    ;

在模板中:

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

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

【讨论】:

如何同时导入select2和jquery?我遇到了麻烦 @Jonathan 我刚刚将它们添加到我的应用程序的入口点 - 在我的例子中是 index.html,如下所示:&lt;script src="node_modules/jquery/dist/jquery.min.js"&gt;&lt;/script&gt; &lt;script src="node_modules/select2/select2.min.js"&gt;&lt;/script&gt; @RadoslavStoyanov 感谢您的回答。知道如何使 jQuery select 2 与 Angular http 和 observable 兼容吗? @RadoslavStoyanov 在最新版本的 Angular 中,它应该是 @azakgaim 是的,我知道 Angular 的版本之间存在一些差异,但问题和答案是关于 Angular2,它使用了这样的语法 :) 谢谢你的评论; )【参考方案2】:

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

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);
    

你可以这样称呼它

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

【讨论】:

以上是关于将 Select2 集成到 Angular2 应用程序中的主要内容,如果未能解决你的问题,请参考以下文章

将 Sails Js 与 Angular 2 集成

Angular2 Material SnackBar 集成问题

如何将 ExpressJS 服务器与 Angular2 集成

将 aws-sdk 集成到 angular2 会给出“找不到模块‘流’”

将 CodeMirror 与 Angular2 集成(打字稿)

集成 TomCat 和 Node 服务器