简体   繁体   中英

Angular: Social share buttons, update URL for Twitter share button

I've built an angular application with routing components. I've tried to add Facebook and Twitter sharing buttons. When navigating to other components through routerlinks, the Facebook and Twitter share buttons correctly update their URL. But when navigating to the same component that is already active with other route params, the Facebook sharing button updates the URL correctly, but the Twitter sharing button doesn't.

I've built a reproduction: https://github.com/MintPlayer/SocialShareButtonsAngular

Now you can test it: - The upper share buttons are from the AppComponent. They won't change when navigating. - The bottom share buttons are located in the routing components, each time again to demonstrate what's happening

  • Home
    • From the homepage, click the bottom Facebook share
    • The url to be shared is: u= https%3A%2F%2F....%2Fhome
    • Click the bottom Tweet button
    • The url to be shared is https://..../home
    • All fine
  • Go to John Wick
    • From the John Wick page, click the bottom Facebook share
    • The url to be shared is: u=https%3A%2F%2F....%2Fperson%2F1 ( /person/1 )
    • Click the bottom Tweet button
    • The url to be shared is https://..../person/1
    • All fine
  • Now navigate to another person (eg. Hannibal Lecter)
    • From the John Wick page, click the bottom Facebook share
    • The url to be shared is: u=https%3A%2F%2Fmintplayer.com%2Fperson%2F2 ( /person/2 )
    • Click the bottom Tweet button
    • The url to be shared is STILL https://..../person/1
    • When switching between items rendered in the same navigation component, the Twitter sharing url isn't updating.

The entire reproduction can be found in this repository: https://github.com/MintPlayer/SocialShareButtonsAngular

There is essential information being printed to the console already.

控制台输出

Inside the FacebookShareComponent and TwitterShareComponent, there's a routerLink input. When the routerLink is being set, the commands array is being computed. The items inside this array are being monitored as well using the IterableDiffers.

  ngAfterViewChecked() {
    const change = this.differ.diff(this.commands);
    if (change !== null) {
      // console.log(change);
      this.updateHref();
      this.reloadTwitterWidgets();
    }
  }

How can I update the Share url for an existing Twitter button? Currently I'm using angular 9.

I finally succeeded by just replacing the HTML back to the state required by the Twitter docs, and calling the widgets.load() function.

export class TwitterShareComponent implements AfterViewChecked {

  constructor(private router: Router, private locationStrategy: LocationStrategy, differs: IterableDiffers, @Inject('BASE_URL') private baseUrl: string) {
    this.differ = differs.find(this.commands).create(null);
  }

  @ViewChild('wrapper') wrapper: ElementRef<HTMLDivElement>;
  differ: IterableDiffer<any>;

  ngAfterViewChecked() {
    const change = this.differ.diff(this.commands);
    if (change !== null) {
      this.updateHref();
      this.reloadTwitterWidgets();
    }
  }

  //#region url
  href: string;
  private commands: any[] = [];
  @Input() set routerLink(value: string | any[]) {
    if (value === null) {
      this.commands = [];
    } else if (Array.isArray(value)) {
      this.commands = value;
    } else {
      this.commands = [value];
    }
    this.updateHref();
    this.reloadTwitterWidgets();
  }
  //#endregion


  private updateHref() {
    let urlTree = this.router.createUrlTree(this.commands);
    let urlSerialized = this.router.serializeUrl(urlTree);
    this.href = this.baseUrl + this.locationStrategy.prepareExternalUrl(urlSerialized);
    console.log(`Twitter share href: ${this.href}`);
  }

  private reloadTwitterWidgets() {
    if (typeof window !== 'undefined') {
      setTimeout(() => {
        this.wrapper.nativeElement.innerHTML = `<a href="https://twitter.com/share" class="twitter-share-button" data-url="${this.href}" data-size="${this.size}" data-text="${this.text}" data-count="none">Tweet</a>`;
        window['twttr'] && window['twttr'].widgets.load();
      }, 10);
    }
  }

  @Input() text: string = '';
  @Input() size: 'large' | 'small' = 'large';
}

And the HTML

<div class="wrapper" #wrapper></div>

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