angularjs - Dynamisk ruttinläsning i Angular 2 misslyckas. (Beta)
Jag vill ladda rutter för @RouteConfig dynamiskt från en tjänst som hämtar i JSON-format,
[
{ "path" : "/about" , "name" : "About" , "component" : "AboutComponent" },
{ "path" : "/contact" , "name" : "Contact" , "component" : "ContactComponent" }
]
Följande är koden för att trycka in den i RouteDefinition-arrayen,
for (let i = 0; i < data.length; i++) {
//console.log(data[i].path+" "+data[i].name+" "+data[i].component);
this.routeConfigArray.push({ //routeConfigArray : RouteDefinition
'path': data[i].path,
'name': data[i].name,
'component': data[i].component
});
this._router.config(this.routeConfigArray); // THIS FAILS TO CONFIG PATHS ON ROUTER
}
The 'component':data[i].component kräver Classname, medan det får det via en String-klass. Hur konverterar jag strängen som innehåller klassnamn till en klass??
Jag har också försökt med Route-klassen genom att använda:
this.routeConfigArray.push(new Route({path: data[i].path, name: data[i].name, component:data[i].component}));
Konsolfel:
Komponenten för rutten '/about' är inte definierad eller är inte en klass. Jag har försökt på många sätt, till exempel att använda
eval("new "+data[i].component+"()); || new window[data[i].component] .
Jag sitter fast vid detta och är verkligen förvirrad över hur jag ska lösa det.
Svar #1
TypeScript kompilerar importeringar till javascript på ett visst sätt, du kan prova något liknande för att kunna använda eval() (pinsamt). Detta kommer uppenbarligen inte att fungera om TypeScript kompilerar på ett annat sätt, men det är roligt att kolla om detta fungerar ändå :)
for (let i = 0; i < data.length; i++) {
this.routeConfigArray.push({ //routeConfigArray : RouteDefinition
path: data[i].path,
name: data[i].name,
component: getComponent(data[i].component)
});
this._router.config(this.routeConfigArray);
}
function getComponent(comp : string) : Function {
//convert camelCase to underscore notation
let component : string = comp;
component = component[0].toLowerCase() + component.slice(1);
component = component.replace(/([A-Z])/g, function(match) {
return '_' + match.toLowerCase();
});
component += '_1';
return eval(component[comp])
}
TILLÄGG
Som ett tillägg till din egen lösning med att använda en AsyncRoute, tror jag faktiskt att du har en ganska bra lösning på gång. Kanske, om du placerar alla sidor på ett visst sätt, kan du extrahera resource-platsen från path, men det är inte nödvändigt. (Jag menar, att få från path-strängen /about till resource-strängen ./app/about/about.component borde inte vara svårt med en liten algoritm. Men det kan vara något för en uppdatering.
Hur som helst, du kan prova något liknande med AsyncRoute
varning: otestad kod framför
let routes : any[] = [
{ "path" : "/about" , "name" : "About" , "component" : "AboutComponent", "route": "/About" , "resource" : "./app/about/about.component" },
{ "path" : "/contact" , "name" : "Contact" , "component" : "ContactComponent", "route": "/Contact" , "resource" : "./app/contact/contact.component" }
];
routes.forEach((route : any) => {
this.routeConfigArray.push(
new AsyncRoute({
path : route.path,
loader : () => System.import(route.resource).then(m => m[route.component]),
name : route.name
})
);
});
this._router.config(this.routeConfigArray);
Svar #2
Du är för bra @PierreDuc, jag tittade precis på regex för att bygga samma funktion, några ändringar jag skulle vilja påpeka för att få det i fungerande skick....
for (let i = 0; i < data.length; i++) {
this.routeConfigArray.push({ //routeConfigArray : RouteDefinition
'path': data[i].path,
'name': data[i].name,
'component': getComponent(data[i].component).constructor
});
this._router.config(this.routeConfigArray);
}
function getComponent(comp : string) : Function {
//convert camelCase to underscore notation
let component : string = comp;
component = component[0].toLowerCase() + component.slice(1);
component = component.replace(/([A-Z])/g, function(match) {
return '_' + match.toLowerCase();
});
component += '_1.';
return eval("new "+component+comp+"()")
}
Tack igen grabben, det är nu i körläge!!! Phu!
