angular - এনজি 2-গতিশীলভাবে কোনও টেমপ্লেটের উপর ভিত্তি করে একটি উপাদান তৈরি করা




angular2-components angular2-injection (2)

আমি গতিশীল উপাদান তৈরির জন্য ComponentResolver এবং ডায়নামিক কম্পোনেন্টসেসলভারের DynamicComponentResolver 2 DynamicComponentResolver , তবে আমি সেই DynamicComponentResolver অফারের চেয়ে আলাদা কিছু মনে করি।

এনজি 2 এর কোন শ্রেণীর নামের একটি স্ট্রিংয়ের উপর ভিত্তি করে কোনও উপাদান তৈরি করার কোনও উপায় আছে?

উদাহরণস্বরূপ, আমি একটি কনফিগারযোগ্য চার্ট ড্যাশবোর্ড তৈরি করছি। প্রতিটি ব্যবহারকারীর বিন্যাস ডাটাবেসে সঞ্চিত থাকে, এখানে উল্লেখ করে যে তারা এখানে 2x লাইন চার্ট চান, সেখানে 3x বার চার্ট ইত্যাদি want

আমি যখন এই ডেটাটিকে জসন হিসাবে লোড করি তখন মনে হয় এটির মতো:

user.charts = [
     { type: 'LineChartComponent', position: ... }
     { type: 'BarChartComponent', position: ... }
];

যেখানে type হ'ল উপাদানটির শ্রেণীর নাম যা আমি প্রতিফলিতভাবে তৈরি করতে চাই।

এখন পর্যন্ত আমার কাছে নিম্নলিখিতগুলি রয়েছে:

 this.chartMap = {
    'LineChartComponent': LineChartComponent
 };

let config = this.configuration;
let chartComponentType = this.chartMap[config.type];
let factory = this.componentFactory.resolveComponentFactory(chartComponentType);
let component = factory.create(this.injector);
component.instance.configuration = config;
this.chartContainer.insert(component.hostView);

তবে পুরো ধারণাটি হল chartMap প্রয়োজনীয়তা দূর করা chartMap প্রকারের কোনও রেফারেন্স না রেখে আমি কীভাবে প্রতিবিম্বিতভাবে এই শ্রেণিটি তৈরি করতে পারি?


এটি আমদানির মাধ্যমে পুনরাবৃত্তি করাও সম্ভব:

import * as possibleComponents from './someComponentLocation'
...
let inputComponent;
for(var key in possibleComponents ){
      if(key == componentStringName){
          inputComponent = possibleComponents[key];
          break;
      }
 }

আপডেট: বা কেবল :-)

let inputComponent = possibleComponents[componentStringName]

তারপরে আপনি উদাহরণস্বরূপ উপাদানটির উদাহরণ তৈরি করতে পারেন:

if (inputComponent) {
    let inputs = {model: model};
    let inputProviders = Object.keys(inputs).map((inputName) => { return { provide: inputName, useValue: inputs[inputName] }; });
    let resolvedInputs = ReflectiveInjector.resolve(inputProviders);
    let injector: ReflectiveInjector = ReflectiveInjector.fromResolvedProviders(resolvedInputs, this.dynamicInsert.parentInjector);
    let factory = this.resolver.resolveComponentFactory(inputComponent as any);
    let component = factory.create(injector);
    this.dynamicInsert.insert(component.hostView);
}

নোট করুন যে উপাদানটি @NgModule এন্ট্রি কম্পোনেন্টগুলিতে থাকতে হবে


Update2:

ক্লাসনেম সহ মন্তব্য সংস্করণে @ ইস্টাস উল্লিখিত হিসাবে মিনিফিকেশনটি কাজ করবে না। এটি আপনি কি পারবেন তা দিয়ে কাজ করার জন্য

1) আপনার প্রতিটি entryComponents কিছু স্থির কী যুক্ত করুন:

export LineChartComponent {
  static key = "LineChartComponent";
}

এবং তারপরে এই key অনন্য হিসাবে ব্যবহার করুন।

const factoryClass = <Type<any>>factories.find((x: any) => x.key === compClassKey);

2) অভিধান তৈরি করুন

export const entryComponentsMap = {
  'comp1': Component1,
  'comp2': Component2,
  'comp3': Component3
};

এবং তারপর

const factory = this.resolver.resolveComponentFactory(entryComponentsMap.comp1);

Update1:

উপাদানটির শ্রেণীর নাম থেকে সংস্করণ এখানে

const factories = Array.from(this.resolver['_factories'].keys());
const factoryClass = <Type<any>>factories.find((x: any) => x.name === compClassName);
const factory = this.resolver.resolveComponentFactory(factoryClass);

পুরাতন রুপ

আপনি উপাদান নির্বাচনকারীর দ্বারা কারখানা পেতে পারেন তবে আপনাকে ব্যক্তিগত সম্পত্তি ব্যবহার করতে হবে।

এটি দেখতে কিছু দেখতে লাগবে:

const factories = Array.from(this.resolver['_factories'].values());
const factory = factories.find((x: any) => x.selector === selector);

Plunker উদাহরণ







angular2-injection