简体   繁体   中英

Angular: Asnyc pipe not updating view until the view is interacted with

I have a simple service ( ActionBarService ) that emits TemplateRefs . In my app-component, I subscribe to the stream using the async pipe. The value gets emitted and logged as expected, but the view does not update and render the new template until I interact with the page in some way. The code is below, thank you in advance!

ActionBarService:

@Injectable({
  providedIn: 'root'
})
export class ActionBarService {
  actionBarTemplate$: BehaviorSubject<TemplateRef<any>>;

  constructor() {
    this.actionBarTemplate$ = new BehaviorSubject(null);
  }

  getTemplate(): BehaviorSubject<TemplateRef<any>> {
    return this.actionBarTemplate$;
  }

  setTemplate(actionBarTemplate: TemplateRef<any>) {
    this.actionBarTemplate$.next(actionBarTemplate);
  }
}

App-Component html:

 <ng-container *ngIf="actionbarTemplate$ | async as actionbarTemplate">
      <ng-container [ngTemplateOutlet]="actionbarTemplate"></ng-container>
  </ng-container>

App-Component

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit, DoCheck {
  title = 'Lets Train';
  @ViewChild('toolbar')
  primaryToolbar: ElementRef;
  toolbarHeight: number;
  actionbarTemplate$: BehaviorSubject<TemplateRef<any>>;

  constructor(public responsiveService: ResponsiveService, private actionBarService: ActionBarService, private router: Router) {
    this.onResize();
  }

  ngOnInit(): void {
    this.actionbarTemplate$ = this.actionBarService.getTemplate();
    this.actionbarTemplate$.subscribe(r => console.log(r));
  }

  ngDoCheck() {
    this.toolbarHeight = this.primaryToolbar.nativeElement.offsetHeight;
  }

  onRouteChange() {
    this.router.events.subscribe(r => {
      if (this.actionbarTemplate$.getValue() != null) {
        this.actionbarTemplate$.next(null);
      }
    });
  }

  @HostListener('window:resize', ['$event'])
  onResize(event?) {
    const screenSize = ScreenSizeUtils.getScreenSize(window.innerWidth);
    this.responsiveService.setScreenSize(screenSize);
  }

The component sending the value to the service:

@Component({
  selector: 'lt-program-template-view',
  templateUrl: './program-template-view.component.html',
  styleUrls: ['./program-template-view.component.scss']
})
export class ProgramTemplateViewComponent implements OnInit, AfterViewInit {
  program$: Observable<ProgramTemplate>;
  routeData: RouteData;
  calloutCard: CalloutCard;

  @ViewChild('actionBar')
  actionBarTemplate: TemplateRef<any>;

  constructor(route: ActivatedRoute, private router: Router, private actionbarService: ActionBarService
    , private programService: ProgramTemplateService) {}

  ngOnInit() {
    this.buildRouteData();

  }

   ngAfterViewInit(): void {
    this.actionbarService.setTemplate(this.actionBarTemplate);
  }

  updateProgram() {

  }

  delete(program: ProgramTemplate) {
    this.programService.delete(program);
  }

  buildRouteData() {
    this.routeData = new RouteData('Programs', ['/program', 'programindex'], null);
  }
}

Emitting component html

<div fxLayout="column" fxLayoutGap="15px">
  <lt-info-card [calloutCard]="calloutCard" (formSaveEmitter)="updateProgram()"></lt-info-card>

</div>

<ng-template #actionBar>
  <mat-toolbar color="primary" class="nav-bar mat-elevation-z2" ngClass.xs="neg-top-margin"
      ngClass.gt-xs="neg-margin">
      <navigation-button [routeData]="routeData"></navigation-button>
      <responsive-button [label]="'Delete'" [icon]="'delete'" (click)="delete()"></responsive-button>
  </mat-toolbar>
</ng-template>

如果有人遇到类似的情况,我不能保证这将适用于你 - 但在我的情况下似乎问题是我的一个模块中的一些隐藏的依赖性错误。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM