1

如果我将 Twitter 文档 ( https://dev.twitter.com/web/javascript/loading )中的内置函数完全复制到 ngAfterViewInit 函数中,我的应用程序可以完美运行,但是当我切换路线时,小部件也会消失。

这是仅适用于第一页加载的代码:

import { Component, OnInit, OnDestroy, AfterViewInit } from '@angular/core';
import { Router, NavigationEnd, ActivatedRoute, ParamMap, Params } from '@angular/router';
import { Observable, Subscription } from 'rxjs/Rx';

export class ProjectDetailComponent implements OnInit, OnDestroy, AfterViewInit {

constructor(
    private route: ActivatedRoute,
    private router: Router
  ) { }

ngOnInit(){}

ngAfterViewInit(){
  (<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'));
}

}

然后我从中找到了一个可接受的解决方案(Angular 2 上的 Twitter 小部件),但该小部件甚至从第一次加载时就没有显示,也没有错误,所以我什至不知道我错在哪里。

这是永远不会显示 Twitter 小部件且没有任何错误的代码:

import { Component, OnInit, OnDestroy, AfterViewInit } from '@angular/core';
import { Router, NavigationEnd, ActivatedRoute, ParamMap, Params } from '@angular/router';
import { Observable, Subscription } from 'rxjs/Rx';

export class ProjectDetailComponent implements OnInit, OnDestroy, AfterViewInit {

private subscription: Subscription;
constructor(
    private route: ActivatedRoute,
    private router: Router
  ) { }

ngOnInit(){}

ngAfterViewInit(){
  this.subscription = 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.subscription.unsubscribe();
}    
}

基本上,我订阅了小部件数据,NavigationEnd然后取消订阅它ngOnDestroy,所以我仍然可以保留路由切换之间的数据。我相信逻辑是正确的,因为该解决方案也适用于某人,但对我来说,直到此刻它才起作用。

4

3 回答 3

6

试试这个,无需订阅或超时。

ngOnInit() {
   (<any>window).twttr.widgets.load();
}
于 2018-08-08T06:50:24.660 回答
2

我知道这是一个老问题,但我得到了比设置超时更好的解决方案。我在这个问题中作为解决方案发布的代码自 Angular 4 晚期或 Angular 5 早期以来就被破坏了——我不记得了。我也会在那里更新我的答案。

所以,要解决这个问题,只需将代码放在构造函数中(这样小部件在视图之前加载),如下所示:

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();
  }
}

如果我找到任何关于为什么以前的代码被破坏的信息,我会更新这个答案。(或者如果其他人知道,请随时编辑)

于 2017-12-26T15:14:36.507 回答
0

好的,我找到了一种基于此参考的解决方法(如果我在 angularjs 中更改视图,为什么我的 twitter 小部件不会呈现?)。不需要事件订阅,我需要将函数包装成setTimeOut在路由切换之间重新渲染它。请记住还要将setTimeOut函数包装在内部isPlatformBrowser,以便更好地进行预渲染。这是代码:

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);
  }
}
于 2017-11-08T11:28:12.993 回答