Angular: канал перевода — визуальный помощник

Итак, моя область применения заключается в том, что в режиме разработки я показываю на странице строки перевода (например, оранжевым цветом).

Итак, у нас есть канал перевода

import { Pipe, PipeTransform } from '@angular/core';
import { TranslationService } from 'app/services/translation.service';
const getByKey = require('lodash.get');

    @Pipe({
      name: 'translate'
    })
    export class TranslatePipe implements PipeTransform {

      constructor(public _translation: TranslationService) {}

      transform(value: string, args?: string): any {
        console.log('KEY: ', value, 'ENGLISH', args);
        return getByKey(this._translation.store, value) || args;
      }
    }

и мы используем его в нашем представлении, например

{{ 'global.key' | translate 'Translated text' }}

работает отлично...

теперь мы хотели бы очистить те, которые переведены с помощью конвейера.... чтобы они были видны на странице... чтобы дать нашей странице перевода лучший обзор того, что происходит (что было переведено и что до сих пор отсутствует)

Теперь, если бы мы использовали

это было бы просто, было бы что-то вроде этого

import { Pipe, PipeTransform } from '@angular/core';
import { TranslationService } from 'app/services/translation.service';
import { DomSanitizer } from '@angular/platform-browser';
const getByKey = require('lodash.get');

@Pipe({
  name: 'translate'
})
export class TranslatePipe implements PipeTransform {

  constructor(public _translation: TranslationService, private _sanitizer: DomSanitizer) {}

  transform(value: string, args?: string): any {
    console.log('KEY: ', value, 'ENGLISH', args);
    return this._sanitizer.bypassSecurityTrustHtml('<span class="translated">' + (getByKey(this._translation.store, value) || args) + '</span>');
  }
}

но мы не... мы не используем innerHTML.... и реализовать его на кросс-сайте было бы непростой задачей...

так есть ли другой способ поместить оболочку html/css в наши переведенные тексты?

любая идея приветствуется


person DS_web_developer    schedule 05.02.2018    source источник


Ответы (1)


Я думаю, нет способа обернуть его в html без использования [innerHTML] или [outerHTML]. Pipes предназначены для преобразования данных, но не для изменения DOM.

Я вижу возможность использовать компонент вместо канала, где вы легко можете решить эту проблему с помощью @Input.

Но я думаю, что самым простым решением является использование [outerHTML], так как Angular автоматически очищает его. Пока служба перевода не вернет ничего неожиданного, все должно работать (иначе вы получите ошибку):

Чтобы систематически блокировать XSS-ошибки, Angular по умолчанию считает все значения ненадежными. Когда значение вставляется в DOM из шаблона с помощью свойства, атрибута, стиля, привязки класса или интерполяции, Angular очищает и избегает ненадежных значений. (https://angular.io/guide/security)

Измените вид таким образом (обратите внимание, после translate должен быть :

<div [outerHTML]="'global.key' | translate: 'Translated text'"></div>

Измените свою transform-функцию следующим образом:

transform(value: string, args?: string): any {
   console.log('KEY: ', value, 'ENGLISH', args);
   const translation = getByKey(this._translation.store, value);
   return translation ? `<span class="translated">${translation}</a>` : args;
}
person sihu    schedule 05.02.2018
comment
значит, нам нужно было бы пойти и реорганизовать все наши переводы, как это? :/ - person DS_web_developer; 05.02.2018
comment
хорошо, теперь я понимаю. вы не можете изменить существующую часть в представлении, верно? - person sihu; 05.02.2018
comment
ну, я мог бы, но это большие усилия, говоря о днях... поэтому нам нужно сначала изучить другие варианты - person DS_web_developer; 05.02.2018
comment
использует регулярное выражение для рефакторинга опции? Большинство IDE и редакторов поддерживают поиск и замену регулярных выражений. Найдите \{\{ ('.*') \| translate '([^']*)' \}\} и замените его на <div [outerHTML]="$1 | translate: '$2'"></div> (может быть, зависит от редактора) - person sihu; 05.02.2018