How can I include the Telegram login widget in an Angular app?

对着背影说爱祢 提交于 2021-02-10 17:50:41

问题


I want to include the Telegram login widget in my Angular application. For this, you have to include the following script:

<script async src="https://telegram.org/js/telegram-widget.js?5"
  data-telegram-login="bot_name" data-size="large"
  data-auth-url="https://myurl.example/api/telegram"
  data-request-access="write"></script>

Embedding scripts in Angular templates is not allowed, it will just be removed. (However, it is possible to include a script tag via this hack.)

Is there a non-hacky way of including this widget?


回答1:


Not rendering script tags in template code is indeed a design choice from Angular team.

The way to do it is thus:

  1. Add your scripts to index.html - only relevant if it makes sense to load the script globally.
  2. Or Add your script programmatically. The post you refer to can be a solution, but brings in additional complication because it takes the input data from template code. A shorter solution is given here, when you're happy with inputing the parameters from the code-side (and the full issue is instructive too): Github issue #4903. Warning though: adding to the head is not suitable unless you remove it in OnDestroy. Prefer adding in the right DOM element of your component.



回答2:


I created the following component for the Telegram login widget:

The component creates the script tag dynamically and adds the callback function loginViaTelegram(user):

@Component({
  selector: 'app-telegram-login-widget',
  template: `    
<div #script style.display="none">
  <ng-content></ng-content>
</div>`,
  styleUrls: ['./telegram-login-widget.component.css']
})
export class TelegramLoginWidgetComponent implements AfterViewInit {

  @ViewChild('script', {static: true}) script: ElementRef;

  convertToScript() {
    const element = this.script.nativeElement;
    const script = document.createElement('script');
    script.src = 'https://telegram.org/js/telegram-widget.js?5';
    script.setAttribute('data-telegram-login', environment.telegramBotName);
    script.setAttribute('data-size', 'large');
    // Callback function in global scope
    script.setAttribute('data-onauth', 'loginViaTelegram(user)');
    script.setAttribute('data-request-access', 'write');
    element.parentElement.replaceChild(script, element);
  }

  ngAfterViewInit() {
    this.convertToScript();
  }

}

I added the callback function loginViaTelegram to the window object (global space) in a dedicated service:

@Injectable({
  providedIn: 'root'
})
export class TelegramLoginService {    
  init() {
    window['loginViaTelegram'] = loginData => this.loginViaTelegram(loginData);
  }

  private loginViaTelegram(loginData: TelegramLoginData) {
    // If the login should trigger view changes, run it within the NgZone.
    this.ngZone.run(() => process(loginRequest));
  }
}


来源:https://stackoverflow.com/questions/56407518/how-can-i-include-the-telegram-login-widget-in-an-angular-app

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!