如何在Angular应用中包含Telegram登录小部件?

时间:2019-06-01 14:17:58

标签: javascript angular typescript telegram telegram-bot

我想在我的Angular应用程序中包含Telegram login widget。为此,您必须包括以下脚本:

<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>

Angular模板中的嵌入脚本为not allowed,它将被删除。 (但是,可以通过this hack包含脚本标签。)

是否有包含此小部件的非骇客方式?

2 个答案:

答案 0 :(得分:0)

不渲染模板代码中的script标签确实是Angular团队的设计选择。

因此,方法是:

  1. 将脚本添加到index.html -仅在合理地全局加载脚本时才有意义。
  2. 以编程方式添加脚本。您引用的帖子可能是一个解决方案,但由于它从模板代码中获取输入数据,因此带来了更多的麻烦。当您满意地从代码端输入参数(并且整个问题也很有启发性)时,这里提供了一个较短的解决方案:Github issue #4903。不过请注意,除非在head中将其删除,否则不适合添加到OnDestroy中。最好在组件中添加正确的DOM元素。

答案 1 :(得分:0)

我为Telegram登录小部件创建了以下组件:

该组件动态创建脚本标签,并添加回调函数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();
  }

}

我在专用服务的loginViaTelegram对象(全局空间)中添加了回调函数window

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