0
votes

enter image description here

When the Make Duplicate button is clicked I want to duplicate the content of the DashboardComponent and place it (the duplicated DashboardComponent) below the original one (the DashboardComponent is the one with the four dark blue squares with the names of the Heroes).

How to make the duplicate component functionality work? Here is the URL of this Stackblitz projects: https://stackblitz.com/edit/angular-u3m6pq?file=src%2Fapp%2Fapp.component.ts

enter image description here

1
Making a shell component and point url to that component. After you can place directive *ngFor into <app-dashboard> to duplicate it - HungCung

1 Answers

0
votes

There are multiple ways you can go about with this - but I'll try to provide a solution that I would use:

The 'Duplicate' button is in the AppComponent and you want the DashboardComponent duplicated. Since the DashboardComponent is routed, you can't rely on input binding. So, to communicate the click event in AppComponent to the DashboardComponent, I'll be using a service:

@Injectable({
  providedIn: 'root'
})
export class DuplicatorService {

   private count = new BehaviorSubject<number>(1);

   incrementCount() {
      const increment = this.count.value + 1;
      this.count.next(increment);
   }

   get count$() {
      return this.count.asObservable();
   }
}

Then inject the service into your AppComponent to enable the button to update the count in the service:

// app.component.ts

  constructor(private duplicatorService: DuplicatorService) {}

  onClick() {
    this.duplicatorService.incrementCount();
  }

The next step would be to create a new component that would hold all the duplicated DashboardComponents, as well as listen for changes in the count from the newly-created service (you can use the .css and .html files here if you want to style it up a bit):

//dashboard-shell.component.ts

@Component({
  selector: 'app-dashboard-shell',
  template: '<app-dashboard *ngFor="let item of (duplicates$ | async)"></app-dashboard>'

})
export class DashboardShellComponent implements OnInit, OnDestroy {
  duplicates$: Observable<number[]>;
  destroySubject = new Subject<void>();

  constructor(private duplicatorService: DuplicatorService) {}

  ngOnInit() {
    this.duplicates$ = this.duplicatorService.count$.pipe(
      map(count => Array(count)),
      takeUntil(this.destroySubject)
    );
  }

  ngOnDestroy() {
    // do not forget to unsubscribe!
    this.destroySubject.next();
    this.destroySubject.complete();
  }
}

Also, don't forget to update the routing for path 'dashboard' to the shell component:

//app.routing.module.ts

  { path: 'dashboard', component: DashboardShellComponent }

That's about it - this is how I would go about with it. There may be many other ways though!