@dilbert
@dilbert
Forum Replies Created
-
AuthorPosts
-
dilbertParticipant
That works. Thanks!
dilbertParticipantThe other thing I’ve tried is to use an ngFor to define the tabs:
<smart-tabs #tabs id="tabs" class="demoTabsShort" [closeButtons]="true" [closeButtonMode]="'selected'" [addNewTab]="true" (addNewTabClick)="onAddNewTabClick($event)" [reorder]="true"> <smart-tab-item *ngFor="let tab of tabNames" [label]="tab"><app-thing></app-thing></smart-tab-item> </smart-tabs>
Where tabNames is just a list of strings.
When a new tab is added (by appending a new string to the tabNames array), the content of the new tab is the new component. However, the label is not updated and there is an error in the console:
core.mjs:8506 ERROR TypeError: Cannot read properties of undefined (reading 'firstElementChild') at BaseElement._updateTabLabel (smart.tabs.js:34:65344) at BaseElement.propertyChangedHandler (smart.tabs.js:34:1110) at t.updateProperty (smart.button.js:34:75016) at BaseElement.set [as label] (smart.button.js:34:76150) at set label [as label] (smart-webcomponents-…ular-tabs.js:771:54) at Object.ngOnChangesSetInput [as setInput] (core.mjs:1586:26) at setInputsForProperty (core.mjs:11738:17) at elementPropertyInternal (core.mjs:10874:9) at Module.ɵɵproperty (core.mjs:13637:9) at AppComponent_smart_tab_item_6_Template (app.component.html:5:50)
- This reply was modified 1 year, 9 months ago by dilbert.
dilbertParticipantHere is an example that illustrates the issue. The first 2 tabs get a dynamic component, but those that are added later do not.
Template:
<div>Num of smart-tab-items: {{smartItems.length}}</div> <div>Num of tabs: {{numTabs}}</div> <smart-tabs #tabs id="tabs" class="demoTabsShort" [closeButtons]="true" [closeButtonMode]="'selected'" [addNewTab]="true" (addNewTabClick)="onAddNewTabClick($event)" [reorder]="true"> <smart-tab-item [label]="'Tab_1'"><ng-container app-view-ref></ng-container></smart-tab-item> <smart-tab-item [label]="'Tab_2'"><ng-container app-view-ref></ng-container></smart-tab-item> </smart-tabs>
Main component:
import { Component, AfterViewInit, ViewChildren, QueryList, ViewChild } from '@angular/core'; import { TabItemComponent, TabsComponent } from 'smart-webcomponents-angular/tabs'; import { ThingComponent } from './thing.component'; import { ViewRefAnchorDirective } from './view-ref-anchor.directive'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent implements AfterViewInit { // I am expecting this list to be updated when new tabs are added. @ViewChildren(TabItemComponent) smartItems = new QueryList(); @ViewChildren(ViewRefAnchorDirective) anchors = new QueryList(); @ViewChild('tabs', {read: TabsComponent, static: false}) tabs!: TabsComponent; numTabs = 0; ngAfterViewInit(): void { this.tabs.getTabs().then(tabs => { this.numTabs = tabs.length; }); this.anchors.forEach(tab => this.loadComponent(tab)); } onAddNewTabClick(event: Event) { this.tabs.getTabs().then(tabs => { this.numTabs = tabs.length; // At this point this.smartItems only has the original 2 smart-tab-items // It would appear the new tabs are not known to Angular since they aren't // added to the QueryList. // this.anchors also only has the original 2. this.anchors.last references // the second tab. Additional tabs do not get a new component. this.loadComponent(this.anchors.last); }); } loadComponent(viewRefAnchor: ViewRefAnchorDirective) { viewRefAnchor.viewContainerRef.clear(); viewRefAnchor.viewContainerRef.createComponent(ThingComponent); } }
Anchor directive:
import { Directive, ViewContainerRef } from "@angular/core"; /** * An directive to expose the ViewContainerRef to allow components to be dynamically * created and added. */ @Directive({ selector: '[app-view-ref]' }) export class ViewRefAnchorDirective { constructor(public viewContainerRef: ViewContainerRef) { } }
Dynamic component:
import { Component, OnInit } from '@angular/core'; @Component({ selector: 'app-thing', template: '<p>test-component works!</p>' }) export class ThingComponent implements OnInit { constructor() { } ngOnInit(): void { } }
dilbertParticipantWith that method I need the ViewContainerRef for the containing component which I can easily do by adding a custom anchor to smart-tab-item to expose it. However, we a new tab is added via the built in add button, the new smart-tab-item doesn’t have this tag. It also doesn’t get added to a @ViewChildren QueryList. (i.e. @ViewChildren(TabItemComponent) items: QueryList<TabItemComponent>). The items list is never updated with any smart-tab-items created using the add tab button.
Is there an easy way to get ViewContainerRef for the dynamically added smart items?
dilbertParticipantThe mentioned help topic does work, however, as of Angular 15 the ComponentFactoryResolver is deprecated. Is there a newer method? I’m hesitant to base new software off of something that could be removed in the future.
-
AuthorPosts