项目作者: piyalidas10

项目描述 :
Quiz game with Flip Flop animation in Angular 8
高级语言: TypeScript
项目地址: git://github.com/piyalidas10/Quiz-Flip-Flop-Angular.git
创建时间: 2020-03-15T04:21:11Z
项目社区:https://github.com/piyalidas10/Quiz-Flip-Flop-Angular

开源协议:

下载


flipflop Quiz game

create an Interface class for Quiz data by running following command defining the type of values for quiz.

Helpfull Tutorials

https://dzone.com/articles/how-to-dynamically-create-a-component-in-angular
https://github.com/softgandhi/ng2-quiz/blob/master/src/app/quiz/quiz.component.ts

Live URL

https://piyalidas10.github.io/flipflop-quiz/

  1. ng generate class models/Quiz

Run Application

  1. ng serve
  2. localhost:4200/

flipflop Quiz

Dynamically Create a Component in Angular

I have a component “Quizexpand” which you want to load dynamically from “Quizhome” component. To load “Quizexpand” you need a container inside
“Quizhome” component.
The template for QuizhomeComponent is as below:

  1. <div class="flip-card-back" (click)="closeSection(startIndex)">
  2. <ng-template #quizcontainer>
  3. </ng-template>
  4. </div>

As you can see, we have an entry point template or a container template in which we will load QuizexpandComponent dynamically.
In QuizhomeComponent, we need to import the following:

  1. ViewChild, ViewContainerRef, and ComponentFactoryResolver from @angular/core.
  2. ComponentRef and ComponentFactory from @angular/core.
  3. QuizexpandComponent from quizexpand.component.

We can access template using ViewChild inside the Component class. The template is a container in which we want to load the component dynamically. Therefore, we have to access template with ViewConatinerRef.

ViewContainerRef represents a container where one or more views can be attached. This can contain two types of views.

Host Views are created by instantiating a component using createComponent and Embedded Views are created by instantiating an Embedded Template usingcreateEmbeddedView. We will use Host Views to dynamically load QuizexpandComponent.

Let us create a variable called entry which will refer to the template element. In addition, we have injected ComponentFactoryResolver services to the component class, which will be needed to dynamically load the component.

  1. @ViewChild('quizcontainer', { read: ViewContainerRef, static: true }) entry: ViewContainerRef;

Keep in mind that the entryvariable, which is a reference to a template element, has an API to create components, destroy components, etc.

To create a component, let us first create a function. Inside the function, we need to perform the following tasks:

  1. Clear the container.
  2. Create a factory for QuizexpandComponent.
  3. Create a component using the factory.
  4. Pass the value for @Input properties using a component reference instance method.
  5. Putting everything together, the openComponent function will look like the below code:

Putting everything together, the openComponent function will look like the below code:

  1. openComponent(index) {
  2. this.entry.clear();
  3. console.log('openComponent entry => ', this.entry);
  4. const alreadyChoosedAns = this.showAlreadySelectedAns(index);
  5. console.log('alreadyChoosedAns => ', alreadyChoosedAns);
  6. const myFactory = this.resolver.resolveComponentFactory(QuizexpandComponent);
  7. this.myRef = this.entry.createComponent(myFactory);
  8. this.myRef.instance['data'] = this.quizLists[index];
  9. this.myRef.instance['serialno'] = index;
  10. this.myRef.instance['alreadychoosedans'] = alreadyChoosedAns;
  11. this.myRef.instance['chooseVal'].subscribe(event => {
  12. console.log('chooseVal => ', event);
  13. this.checkDuplicateAns(event);
  14. });
  15. this.myRef.changeDetectorRef.detectChanges();
  16. }

click on “expandSection” function this “openComponent” function will be called.

You can destroy a component using the destroy method on the myRef.

  1. closeComponent(index) {
  2. console.log('close component', index);
  3. this.myRef.destroy();
  4. }

At this point, when running the application, you will get an error because we have not set the entryComponents in AppModule. We can set that as shown in the listing below:

  1. import { BrowserModule } from '@angular/platform-browser';
  2. import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
  3. import { HttpClientModule } from '@angular/common/http';
  4. import { CommonModule } from '@angular/common';
  5. import { ReactiveFormsModule } from '@angular/forms';
  6. import { AppComponent } from './app.component';
  7. import { QuizhomeComponent } from './quizhome/quizhome.component';
  8. import { QuizexpandComponent } from './quizexpand/quizexpand.component';
  9. import { ApiService } from './services/api.service';
  10. // import { QuizcontainerDirective } from './quizhome/quizhome.component';
  11. import { QuizresultComponent } from './quizresult/quizresult.component';
  12. @NgModule({
  13. declarations: [
  14. AppComponent,
  15. QuizhomeComponent,
  16. // QuizcontainerDirective,
  17. QuizexpandComponent,
  18. QuizresultComponent
  19. ],
  20. imports: [
  21. BrowserModule,
  22. CommonModule,
  23. HttpClientModule,
  24. ReactiveFormsModule
  25. ],
  26. schemas: [
  27. CUSTOM_ELEMENTS_SCHEMA
  28. ],
  29. providers: [ApiService],
  30. entryComponents: [
  31. QuizexpandComponent
  32. ],
  33. bootstrap: [AppComponent]
  34. })
  35. export class AppModule { }