2016-06-01 18 views
3

Für eine I18n-ähnliche Komponente möchte ich einen Komponenteninhalt als String erhalten, um einen Fallback-Wert zu haben, falls mein I18n-Dienst nichts bekommt, dieser Wert soll ein Fallback sein.Get Komponente als String

I18n Service get Methode:

public get(key:string, 
       defaultValue?:string, 
       variables:Variables = {}, 
       domain?:string):string { 

     for (let catalogue of this.catalogues) { 
      if (catalogue.getDomains().indexOf(domain) >= 0 
       && catalogue.getLocale() == this.locale 
       && catalogue.hasKey(key)) { 
       return I18n.setVariables(catalogue.get(key, domain, defaultValue).value, variables); 
      } 
     } 
     return defaultValue; 
    } 

I18nComponent:

@Component({ 
    selector: "i18n", 
    template: "{{text}}", 
}) 
export class I18nComponent implements OnInit { 

    constructor(private i18n:I18n) { 
    } 

    @ContentChild() content:string; //Here, I want to store actual value as fallback one. 

    @Input('key') key:string; 

    @Input('domain') domain:string; 

    @Input('variables') 
    variables:Variables = []; 

    @Input("plural") 
    plural:number; 

    text:string; 

    ngOnInit():any { 
     console.log(this.content); //Here I get 'undefined' 
     if (this.plural !== undefined && this.plural != null) { 
      this.text = this.i18n.get(this.key, this.content, this.variables, this.domain); 
     } else { 
      this.text = this.i18n.getPlural(this.key, this.plural, this.content, this.variables, this.domain); 
     } 
    } 
} 

Verwendungsbeispiel:

<i18n key="FOO_KEY" domain="stackoverflow">I'm the default value !</i18n> 

Ich weiß <ng-content></ng-content> Werke, sondern nur auf der Logik-Vorlage, ich brauche einen Weg Kind als Zeichenfolge in Typoskript erhalten.

Bereits versucht @ContentChild(String), aber ich habe undefined. Eine andere Möglichkeit wäre, es wie "Loading ..." String zu tun, die Sie in der Basis app Komponente im Index haben können, die wie ein Platzhalter wirkt, bis Sie alles geladen bekommen. Ich könnte das gleiche für I18n tun, lassen Sie den Lakeholder hier, bis ich etwas vom Dienst erhalte, um es zu ersetzen, aber ich weiß nicht, wie man das erreicht.

+0

ich nicht bekommen, was Sie zu erreichen versuchen. Wie steht es mit Ihrem I18n-Service? Warum sollte man nicht einfach den Fallback-Wert in die Klasse einfügen und dann den einen aus dem Service binden und wenn nicht verfügbar, den Fallback? –

+0

Ich kann den Fallback-Wert in der Klasse nicht festlegen, da es nicht immer gleich ist. Ich habe ein Fallback für jede i18n-Komponente Verwendung, und es kann HTML-Tags enthalten. (Beispiel: 'Sie gewonnen' -> fallback = 'Sie gewonnen'). Der Fallback ist hier "nur für den Fall", dann, wenn ich den Wert nicht durch den Service bekomme, zeige ich den englischen (den Fallback). – Supamiu

+0

Können Sie bitte ein vollständiges Beispiel hinzufügen. Ich komme nicht von deiner Frage, was genau du zu erreichen versuchst. –

Antwort

4

Sie können @ContentChildren() nicht verwenden, um den gesamten Inhalt zu erhalten. Sie können entweder ein Template-Variable und Abfrage für seinen Namen hinzufügen:

<i18n key="FOO_KEY" domain="stackoverflow"><span #myVar>I'm the default value !</span></i18n> 
@ContentChild('myVar') myVar; 

ngAfterContentInit() { 
    console.log(this.myVar.nativeElement.innerHTML); 
} 

myVar nicht initialisiert werden, bevor ngAfterContentInit() aufgerufen wird.

Alternativ @ContentChild() (oder @ContentChildren()) Sie für einen Komponenten abfragen Typ wie

<i18n key="FOO_KEY" domain="stackoverflow"><my-comp>I'm the default value !</span></i18n> 

@ContentChild(MyComponent, {read: ElementRef}) mycomp; 

ngAfterContentInit() { 
    console.log(this.myVar.nativeElement.innerHTML); 
} 

ich dieser Ansatz besser denken für Sie arbeiten wird

@Component({ 
    selector: "i18n", 
    template: "<div #wrapper hidden="true"><ng-content></ng-content><div>{{text}}", 
}) 
export class I18nComponent implements OnInit { 

    constructor(private i18n:I18n) { 
    } 

    @ViewChild('wrapper') content:ElementRef; //Here, I want to store actual value as fallback one. 

    @Input('key') key:string; 

    @Input('domain') domain:string; 

    @Input('variables') 
    variables:Variables = []; 

    @Input("plural") 
    plural:number; 

    text:string; 

    ngAfterViewInitInit():any { 
     console.log(this.content.nativeElement.innerHTML); 
     if (this.plural !== undefined && this.plural != null) { 
      this.text = this.i18n.get(this.key, this.content, this.variables, this.domain); 
     } else { 
      this.text = this.i18n.getPlural(this.key, this.plural, this.content, this.variables, this.domain); 
     } 
    } 
} 

Ansatz Wenn Sie die Benutzer Ihrer i18n wollen Komponente, um in der Lage zu sein, Winkelbindungen, Komponenten und Direktiven in dem Inhalt zu verwenden, den sie an <i18n> übergeben, dann muss er es in einer Vorlage einwickeln.

<i18n key="FOO_KEY" domain="stackoverflow"> 
     <template> 
     I'm the {{someName}}! 
     <my-comp (click)="doSomething()"></my-comp> 
     </template> 
    </i18n> 

wie erklärt in https://stackoverflow.com/a/37229495/217408

+0

Seltsamerweise musste ich '{{text}}' an die Vorderseite der Vorlage anstatt an das Ende setzen. –