2

我想对 ng2-select 中的项目使用 ngx-translate。我能想到的唯一方法是在绑定之前使用翻译服务并在 ts 文件中改变项目的文本。

有没有办法使用管道或指令,因为我想让它保持一致。

提前致谢。

4

3 回答 3

3

我的解决方案是创建一个管道并将其用于选择的项目:

<ng-select [items]="listOfTimeOfExecution | selectOptionsTranslate" ...

和管道代码:

import { Pipe, PipeTransform } from '@angular/core';
import { TranslateService } from 'ng2-translate/ng2-translate';
import { SelectOption } from 'app/shared/entities';

@Pipe({name: 'selectOptionsTranslate'})
export class SelectOptionsTranslatePipe implements PipeTransform {
    constructor(public translateService: TranslateService){}

    transform(items: Array<SelectOption>) : Array<SelectOption> {
        for(let item of items) {
            item.text = this.translateService.instant(item.text);
        }
        return items;
    }
}
于 2018-02-24T22:40:04.267 回答
3

我的解决方案受到Iosif 的启发,由于 translateService的异步特性,我无法使其正常工作

其次,当用户更改语言时,我还需要翻译选项。

所以这是我处理上述两个问题的解决方案(我也写了一个管道):

依赖项:
Angular 6
“@ng-select/ng-select”:“2.5.1”,
“@ngx-translate/core”:“^10.0.2”,


translate-options.pipe.ts
(Rmbr 将其导入到 app.module.ts 的声明数组中)

// ... Rmbr to import the libs ...

@Pipe({
  name: 'translateOptions',
})
export class TranslateOptionsPipe implements PipeTransform, OnDestroy {

  constructor(private translateService: TranslateService) { }


  transform(items: any) {    
    const observable = Observable.create(observer => {
        this.translateService.get(items).subscribe(result => {            
            // result will be an object
            // e.g. { 'JOBS.UX': 'UX Designer', 'JOBS.DEVELOPER': 'Developer' }
            observer.next(result);
        });        

        this.translateService.onLangChange.subscribe(event => {
            this.translateService.get(items).subscribe(result => {            
                observer.next(result);
            });
        })
    });

    return observable;
  }

  ngOnDestroy() {
    this.translateService.onLangChange.unsubscribe();
  }
}

下面代码中的app.component.html
将是一个翻译键数组,例如:
['JOBS.DEVELOPER', 'JOBS.UX', 'JOBS.PM']

<ng-select
    [addTag]="true"
    [addTagText]="to.addTagText || 'Create item: '"
    [multiple]="to.multiple"
    [closeOnSelect]="!to.multiple"
    (change)="onAutoCompleteChange($event)"  
>
    <ng-option
        *ngFor="let item of items | translateOptions | async | keyvalue" 
        [value]="item.key"
    >
        {{ item.value }}
    </ng-option>
</ng-select>

希望有帮助

于 2018-08-28T10:39:14.553 回答
0

使用下拉列表的父级将传递一个类型如下的对象到下拉组件。

export interface IDropdownOptions {
  items: any[];
  itemType: 'action' | 'divider';
  itemLabel: (item: any) => string;

  itemClicked?: (item: any) => void; // overwriting default onChange function
  itemVisible?: (item: any) => boolean;
  itemSelectable?: (item: any) => boolean;

  selectedText: (() => string) | string;
  shortSelectedText?: (() => string) | string;
  // can define more for styling and custom purposes...
}

然后我有我的下拉组件来实现 ControlValueAccessor 以角度形式可用

import { Component, forwardRef, Input, } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { get } from 'lodash';

@Component({
  selector: 'c-dropdown',
  templateUrl: './dropdown.component.html',
  providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => DropdownComponent), multi: true }]
})
export class DropdownComponent implements ControlValueAccessor {
  @Input() options: IDropdownOptions;
  onChange: any = () => {};

  get itemLabel(): (item: any) => string {
    return !!get(this.options, 'itemLabel')
      ? this.options.itemLabel
      : () => '';
  }

  get itemClicked(): (item: any) => void {
    !!get(this.options, 'itemClicked')
      ? this.options.itemClicked
      : this.onChange;
  }

  // Getter functions for itemSelectable, itemVisible, etc.

  constructor() {}

  // Other inherited functions...

  registerOnChange(fn: any): void {
    this.onChange = fn;
  }

}

在模板的 for 循环中,您可以使用带有 itemLabel(item) 的翻译管道。

于 2018-03-10T00:22:13.273 回答