2017-11-03 4 views
0

Ich lerne derzeit JavaScript, ich habe einige Bücher für die letzten Tage gelesen, aber ich möchte etwas Hilfe mit dem folgenden.Cleaner Weg zum Verbergen Multipleple Object Cache innerhalb Instanz

Nehmen wir an, wir haben eine Klasse mit dem Namen Label. Sein Konstruktor akzeptiert ein data Objekt, das einige Übersetzungen enthält. Ich möchte diese Übersetzungen in einer Label-Instanz "verstecken" und die Eigenschaft text dem Rest des Programms zugänglich machen.

Eine Lösung wäre, die eine Eigenschaft _active eine Übersetzung aus _translations Referenzierung einer Getter-Methode active() Übersetzung von _active referenzierten Rückkehr und ein setLang() Verfahren zwischen Übersetzungen zu schalten. Aber das würde uns zwingen, immer active auf einer Label-Instanz zu rufen, um seinen Text zu erhalten, wie label.active.text.

(Ich bin mir bewusst, dass das _translations Objekt nicht wirklich verborgen ist, da es nicht privat ist. Die Label Klasse kann nicht viel Sinn machen, dann ist es schnell Beispiel kam ich mit, aber das _translations Objekt kann ein Cache für Übersetzungen werden wir über einen API-Aufruf erhalten.)

Es muss sicherlich eine sauberere Art der Umsetzung von etwas wie dies, möglicherweise die active Methode Anruf auf dem Etikett zu vermeiden. Irgendwelche Ideen?

Ich könnte eine get text(){ return this._active.text } haben, aber was wäre, wenn das Übersetzungsobjekt viele Eigenschaften hätte?

Vielen Dank im Voraus!

const data = { 
 
    // these objects could possibly have more properties 
 
    en: {text: 'Text in english.'}, 
 
    zh: {text: "Let's imagine this one is in chinese."} 
 
}; 
 

 
class Label { 
 
    constructor(data) { 
 
     this._translations = {}; 
 
     for (let lang in data) 
 
      this._translations[lang] = data[lang]; 
 
     this._active = this._translations.en; 
 
    } 
 

 
    get active() { 
 
     return this._active; 
 
    } 
 

 
    // switch between translations 
 
    // may be used to get translations from an API endpoint 
 
    // if the translation exists, read from _translations cache 
 
    // if not, fetch from server (not implemented) 
 
    setLang(value) { 
 
     return (this._translations[value] && 
 
      (this._active = this._translations[value])) !== undefined; 
 
    } 
 
} 
 

 
let label = new Label(data); 
 
console.log(label.active.text); 
 

 
label.setLang('zh'); 
 
console.log(label.active.text); 
 

 
// I'd like to simply call label.text to return the text

+0

Warum sollte ein einzelnes 'Label' haben mehrere Texte? Dieser '.text' Getter ist der Weg zu gehen. – Bergi

+0

Hallo @Bergi, danke für deine Kommentare. Die Klasse "Label" ist nur ein Beispiel. Nehmen wir an, dass jedes Objekt in "data" mehr als nur die Eigenschaft 'text' enthält. Oder noch besser, eine Reihe von Eigenschaften dynamisch erstellt. Wie würdest du damit umgehen? –

+0

Mit einer 'getTranslation (" text ") Methode wahrscheinlich. Sie können auch einen 'Proxy' erstellen, um alle Eigenschaftenzugriffe auf diese Methode als syntaktischen Zucker zu delegieren. – Bergi

Antwort

0

Nach @ Bergi Vorschlag einen Proxy zu verwenden, kam ich mit dem folgenden auf das mein Problem nicht lösen. Es kommt mit den Kosten für die Verwendung eines Proxy, aber es ist gut genug für das, was ich brauche.

const data = { 
 
    en: { 
 
    text: 'Text in english.', 
 
    color: 'red' 
 
    }, 
 
    zh: { 
 
    text: "Let's imagine this one is in chinese.", 
 
    color: 'red in chinese' 
 
    } 
 
}; 
 

 
class Label { 
 
    constructor(data) { 
 
    this._translations = {}; 
 
    for (let lang in data) 
 
     this._translations[lang] = data[lang]; 
 
    this._active = this._translations.en; 
 
    
 
    // the 'new' operator passes an emtpy {} to the constructor 
 
    // the constructor returns that object in the end 
 
    // the 'this' now is said object (a 'Label') 
 
    
 
    // then we wrap that object with a prox 
 
    // that proxy redirects all calls to the active label 
 
    return new Proxy(this, { 
 
     get: function(target, name) { 
 
     if (name in target['_active']) 
 
      return target['_active'][name]; 
 
     return target[name]; 
 
     } 
 
    }); 
 
    } 
 

 
    get active() { 
 
    return this._active; 
 
    } 
 

 
    hi() { 
 
    console.log(this); 
 
    } 
 

 
    setLang(value) { 
 
    return (this._translations[value] && 
 
     (this._active = this._translations[value])) !== undefined; 
 
    } 
 
} 
 

 
window.label = new Label(data); 
 
console.log(label); 
 
console.log(label.text); 
 
label.setLang('zh'); 
 
console.log(label.text);

Verwandte Themen