انگولارجاس - بارگذاری مسیر پویا در انگولار ۲ شکست میخورد. (بتا)
من میخواهم مسیرها برای @RouteConfig را بهصورت دینامیک از یک سرویس که به فرمت JSON دریافت میکند بارگذاری کنم.
[
{ "path" : "/about" , "name" : "About" , "component" : "AboutComponent" },
{ "path" : "/contact" , "name" : "Contact" , "component" : "ContactComponent" }
]
در ادامه کد برای قرار دادن آن در آرایه RouteDefinition آمده است،
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
}
کد 'component':data[i].component نیاز به Classname دارد، در حالی که آن را از طریق یک رشته کلاس دریافت میکند. چگونه میتوانم رشتهای که شامل نام کلاس است را به یک کلاس تبدیل کنم؟
همچنین من کلاس Route را با استفاده از : امتحان کردهام
this.routeConfigArray.push(new Route({path: data[i].path, name: data[i].name, component:data[i].component}));
خطای کنسول:
کامپوننت برای مسیر '/about' تعریف نشده است یا یک کلاس نیست. من راههای مختلفی مانند استفاده از
eval("new "+data[i].component+"()"); || new window[data[i].component]را امتحان کردهام
من در این مورد گیر کردهام و واقعاً نمیدانم چگونه باید آن را حل کنم.
پاسخ شماره ۱
تایپاسکریپت ایمپورتها را به یک روش خاص به جاوااسکریپت کامپایل میکند، شما میتوانید چیزی شبیه به این را امتحان کنید تا بتوانید از eval() استفاده کنید (ناخوشایند). واضح است که اگر تایپاسکریپت به روش دیگری کامپایل کند، این کار جواب نخواهد داد، اما جالب است بررسی کنید که آیا به هر حال کار میکند یا نه :)
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])
}
ضمیمه
علاوه بر راهحل خودتان با استفاده از AsyncRoute، من فکر میکنم در واقع شما راهحل نسبتاً خوبی پیدا کردهاید. شاید اگر همه صفحات را به یک روش خاص مرتب کنید، بتوانید مکان resource را از path استخراج کنید، اما این ضروری نیست. (منظورم این است که گرفتن رشته path /about و تبدیل آن به رشته resource ./app/about/about.component با یک الگوریتم کوچک نباید سخت باشد. اما این ممکن است چیزی باشد برای بهروزرسانی.
به هر حال، میتوانید چیزی شبیه این را با AsyncRoute امتحان کنید
هشدار: کد تست نشده در پیش است
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);
پاسخ شماره ۲
تو خیلی خوب هستی @PierreDuc، من فقط داشتم به regex نگاه میکردم تا همان عملکرد را بسازم، چند ویرایشی هست که میخواهم آنها را اشاره کنم تا به حالت عملیاتی برسد....
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+"()")
}
باز هم ممنون داداش، الان در حالت اجراست!!! فیو!
