embedded Twitter widget on Angular 2+ app only shows up on the first page load

后端 未结 3 1221
醉梦人生
醉梦人生 2021-01-07 11:23

My app works perfectly if I copy exactly the built-in function from Twitter docs (https://dev.twitter.com/web/javascript/loading) into ngAfterViewInit function, but when I s

相关标签:
3条回答
  • 2021-01-07 11:35

    Okay, I found a way to work around based on this reference (Why will my twitter widget not render if i change the view in angularjs?). No need for event subscription, I need to wrap the function into setTimeOut to re-render it between route switch. Remember to also wrap the setTimeOut function inside isPlatformBrowser for a better practice of pre-rendering. Here is the code:

    import { Component, OnInit, OnDestroy, AfterViewInit, PLATFORM_ID, Inject } from '@angular/core';
    import { isPlatformBrowser } from '@angular/common';
    
    constructor(@Inject(PLATFORM_ID) private platformId: Object) { }
    
    ngAfterViewInit() {    
     if (isPlatformBrowser(this.platformId)) {
      setTimeout(function() { 
        (<any>window).twttr = (function(d, s, id) {
          let js, fjs = d.getElementsByTagName(s)[0],
            t = (<any>window).twttr || {};
          if (d.getElementById(id)) return t;
          js = d.createElement(s);
          js.id = id;
          js.src = 'https://platform.twitter.com/widgets.js';
          fjs.parentNode.insertBefore(js, fjs);
    
          t._e = [];
          t.ready = function(f) {
            t._e.push(f);
          };
    
          return t;
        }(document, 'script', 'twitter-wjs'));
        (<any>window).twttr.widgets.load(); }, 100);
      }
    }
    
    0 讨论(0)
  • 2021-01-07 11:47

    I know this is an old question, but I got a better solution than setting a timeout. The code I posted as solution in this question is broken since late Angular 4 or early Angular 5 - I don't remember. I will update my answer there too.

    So, to fix this, just put the code in the constructor (so the widget loads before the view) like so:

    import { Component, OnDestroy } from '@angular/core';
    import { Router, NavigationEnd } from '@angular/router';
    
    @Component({ ... })
    
    export class HomeComponent implements OnDestroy {
      private twitter: any;
    
      constructor(private _router: Router) {
        this.initTwitterWidget();
      }
    
      initTwitterWidget() {
        this.twitter = this._router.events.subscribe(val => {
          if (val instanceof NavigationEnd) {
            (<any>window).twttr = (function (d, s, id) {
              let js: any, fjs = d.getElementsByTagName(s)[0],
                  t = (<any>window).twttr || {};
              if (d.getElementById(id)) return t;
              js = d.createElement(s);
              js.id = id;
              js.src = "https://platform.twitter.com/widgets.js";
              fjs.parentNode.insertBefore(js, fjs);
    
              t._e = [];
              t.ready = function (f: any) {
                  t._e.push(f);
              };
    
              return t;
            }(document, "script", "twitter-wjs"));
    
            if ((<any>window).twttr.ready())
              (<any>window).twttr.widgets.load();
    
          }
        });
      }
    
      ngOnDestroy() {
        this.twitter.unsubscribe();
      }
    }
    

    If I find any information on why previous code was broken, I'll update this answer. (Or if anyone else knows, feel free to edit this)

    0 讨论(0)
  • 2021-01-07 11:59

    Try this, no need to subscribe or timeout.

    ngOnInit() {
       (<any>window).twttr.widgets.load();
    }
    
    0 讨论(0)
提交回复
热议问题