如果我将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'));
}
}
然后我找到了一个可接受的解决方案(Twitter widget on Angular 2),但是小部件甚至没有从第一次加载显示,也没有错误,所以我甚至不知道我错在哪里。
这是从未显示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
中取消订阅,所以我仍然可以保留路由切换之间的数据。我相信逻辑是正确的,因为解决方案也适用于某人,但对我来说,它直到现在才开始工作。
答案 0 :(得分:3)
尝试此操作,无需订阅或超时。
ngOnInit() {
(<any>window).twttr.widgets.load();
}
答案 1 :(得分:2)
我知道这是一个老问题,但我得到了一个比设置超时更好的解决方案。我在this问题中作为解决方案发布的代码在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();
}
}
如果我发现有关前一代码被破坏的原因的任何信息,我将更新此答案。 (或者,如果有其他人知道,请随时编辑此内容)
答案 2 :(得分:0)
好的,我找到了一种基于此参考(Why will my twitter widget not render if i change the view in angularjs?)的解决方法。不需要事件订阅,我需要将函数包装到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);
}
}