0

Ist es möglich, auf den Prototyp einer Komponente in Angular zuzugreifen?Wie kann ich den Prototyp der Komponentenklasse aus dem Klassennamen in Angular finden und den Wert der in diesem Klassenprototyp definierten Eigenschaft ermitteln?

Zum Beispiel (dies kehrt nicht den Wert):

console.log(AppSample1Component.prototype.propertyWithDefaultValue); 

Wie kann ich Prototyp einer Klasse in Route Resolver Funktion accces wenn es möglich ist?

resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<any> | Promise<any> | any { 
    const componentType = typeof route.component === 'string' ? route.component : route.component.name; 
    console.log('Class name of the component: ', componentType); 
    console.log('>>> I want to find the prototype of component class from ActivatedRouteSnapshot and get the value of "propertyWithDefaultValue" property of that class prototype in this section.'); 

    return new Promise((resolve, reject) => { 
     Promise.all([ 
      this.getData() 
     ]).then(
      () => { 
       // Init component(s) after prefetch data, etc... 
       resolve(); 
      }, 
      reject 
      ); 
    }); 
} 

Sie können die StackBlitz reproduction of the problem here überprüfen.


bearbeiten

Ich erwähnte Angular, weil ich lernen will, wenn Angular eine interne Methode/Eigenschaft hat Mapping von Klasseneigenschaften Metadaten zu finden, die ich statische Eigenschaften der Klasse im Router-Resolver zugreifen kann Methode. Angular kennt den route.component.name. Also dachte ich mir, dass es einen internen Ort geben könnte, um diese Art von Metadaten zu finden.

// Here's an example which shows a minimal use of OOP in my recent javascript projects 
 
const myLib = { 
 
    apply: function (obj, config) { 
 
     if (obj && config && typeof config === 'object') 
 
      for (var p in config) 
 
       obj[p] = config[p]; 
 
     return obj; 
 
    }, 
 
    extend: function (sc, bc) { 
 
     var Fn = function() {}; 
 
     Fn.prototype = bc.prototype; 
 
     var scpb = sc.prototype; 
 
     var scp = sc.prototype = new Fn(); 
 
     scp.constructor = sc; 
 
     if (bc.prototype.constructor === Object.prototype.constructor) 
 
      bc.prototype.constructor = bc; 
 
     myLib.apply(scp, scpb); 
 
     sc.superclass = bc.prototype; 
 
    } 
 
}; 
 
myLib.textField = function (config) { 
 

 
}; 
 
myLib.textField.prototype = { 
 
    type: 'text' 
 
}; 
 

 
myLib.numberField = function (config) { 
 
\t myLib.numberField.superclass.constructor.call(this, config); 
 
}; 
 
myLib.numberField.prototype = { 
 
    type: 'number', 
 
    min: 0, 
 
    max: 9999 
 
}; 
 
myLib.extend(myLib.numberField, myLib.textField); 
 

 
const obj1 = new myLib.textField(); 
 
const obj2 = new myLib.numberField(); 
 

 
console.group('My old JS way'); 
 
console.log(obj1.type, obj2.type); 
 
console.log(myLib.textField.prototype.max, myLib.numberField.prototype.max); 
 
console.groupEnd(); 
 

 
// And here is a demonstration of typescript generated javascript. 
 
// Compiled typescript code generates javascript class as something like below. 
 
// Typescript places the properties to the beginning of the constructor, not to prototype. 
 
// This is why it's not possible to access class prototype directly. 
 
myLib.numberField2 = function() { 
 
    this.type = 'number'; 
 
    this.min = 0; 
 
    this.max = 9999; 
 
    //constructor block begin 
 
    //constructor block end 
 
}; 
 
const obj3 = new myLib.numberField2(); 
 
console.group('Typescript compiled output demonstration'); 
 
console.log(obj3.max); // prints 9999 
 

 
console.log(myLib.numberField2.prototype.max); 
 
// this prints "undefined" because max property doesn't exist before object creation 
 
console.groupEnd();

+0

Warum denken Sie, es wird 'AppSample1Component.prototype.propertyWithDefaultValue' umgewandelt werden? https://www.typescriptlang.org/play/index.html#src=export%20class%20AppSample1Component%20%7B%0D%0A%20%20public%20propertyWithDefaultValue%20%3D%20'Lorem%20ipsum%20dolor% 20sit% 20amet! '% 3B% 0D% 0A% 7D – yurzui

+0

warum brauchen Sie Prototyp integrierte Klasse setzen bereits? Erweitern Sie es und legen Sie Ihre benutzerdefinierten Variablen in der benutzerdefinierten untergeordneten Klasse fest. – omeralper

+0

@yurzui diese Syntax ist die, die ich eine Klasse Prototyp-Eigenschaft in JavaScript zugreifen wurde mit. Deshalb habe ich es als Beispiel geschrieben. Nicht weil ich denke, dass es sich in diese Form verwandeln sollte. –

Antwort

0

Wenn ich Ihre Frage richtig verstanden, Sie zu fragen: „Ist es möglich, eine Klasse über seinen Namen dynamisch zu lösen?“

Wo Sie versuchen, diesen Code aufzurufen und ob Sie in Angular oder nicht sind, scheint nicht relevant für die Frage.

Die allgemeine Antwort auf die Frage ist "Nein". Klassen/Module haben nicht notwendigerweise einen eindeutigen Namen in Ihrer Anwendung. Sie können sie zum Beispiel umbenennen, wenn Sie sie importieren (z. B. import { LongClassName as LCN } from "./long-class-name";). Und es kann mehrere Klassen mit demselben Namen geben.

Angenommen, Sie haben alle Klassen importiert, die Sie möglicherweise auflösen oder in Ihrem aktuellen Modul definieren möchten, können Sie eval(classNameToResolve).prototype verwenden, um den Klassenprototyp zu erhalten. Es wird jedoch dringend davon abgeraten, aus Sicherheits- und Leistungsgründen von eval Gebrauch zu machen. Und es wird nicht mit allen Modulbundlern funktionieren oder wenn Sie Ihren Code minimieren.

Also, kurz gesagt, nein. Erwägen Sie, ein Mapping zu erstellen, mit dem Sie die gewünschte Suche durchführen können, z.

const ALL_MY_CLASSES = { 
    ClassA: ClassA, 
    ClassB: ClassB 
} 

Dann werden Sie in der Lage sein, die Lookup über ALL_MY_CLASSES[classNameToResolve].prototype zu tun. Sie müssen natürlich alle Klassen hinzufügen, auf die Sie stoßen könnten.

+0

Danke für Ihre Antwort. Ich habe https://jsfiddle.net/hallilibrahim/wvm17c8d/ für eine erweiterte Version der Frage vorbereitet. –

Verwandte Themen