【问题标题】:What is the right way to implement a 3rd party library that manipulates the Dom?实现操纵 Dom 的 3rd 方库的正确方法是什么?
【发布时间】:2019-05-28 03:34:08
【问题描述】:

我正在使用第 3 方库将小部件呈现到屏幕上(Okta 的 SignInWidget)。小部件的呈现方式是这样的:

this.oktaSignInWidget.renderEl(
    { el: '#widget-container' },
    () => {},
    err => {
      console.error(err);
    }
  );

我最初的想法是将其放入指令中,但即使使用指令,您也应该让 Renderer2 进行渲染。这里有最佳做法吗?

【问题讨论】:

    标签: angular angular2-directives angular-renderer2


    【解决方案1】:

    由于小部件可能替换/构建给定容器的内容,这似乎是常规 Angular 组件的经典用例。 看来您也不需要动态实例化(通常在 3rd 方库包含教程中找到)。

    如果您使用选择器 myapp-login 创建组件,您可以将其放入您的一些登录页面:

    <h1>Login</h1>
    <p>Hi people, login to get more features:</p>
    <myapp-login></myapp-login>
    

    大致遵循this Angular University's article about @ViewChild(也简要提及第三方库)、this SO answer 或 Netanel Basal 的文章Using 3rd Party Library Inside Angular2(省略输入),我们可以进行如下操作:

    要访问自定义组件中的元素,您应该让 Angular 通过添加带有 @ViewChild('container') 修饰的 ElementRef 类型属性来注入对带有 #container 标记的元素的引用。

    @ViewChild('container')
    container: ElementRef;
    

    在组件的构造函数中,您可以构建您的小部件实例。

    在您的视图被初始化后,您应该让小部件实例将自身呈现到容器元素中。记得在组件被销毁时销毁小部件(可能通过调用.remove())。

    这是您的登录组件的未经测试的骨架:

    ...
    import OktaSignIn from '@okta/okta-signin-widget';
    import '@okta/okta-signin-widget/dist/css/okta-sign-in.min.css';
    import '@okta/okta-signin-widget/dist/css/okta-theme.css';
    
    @Component({
      selector: 'myapp-login',
      template: '<div #container></div>'
    })
    export class Login implements AfterViewInit, OnDestroy {
      @ViewChild('container')
      container: ElementRef;
    
      oktaSignInWidget: OktaSignIn;
    
      constructor() {
        this.oktaSignInWidget = new OktaSignIn({baseUrl: 'https://{yourOktaDomain}'});
      }
    
      ngAfterViewInit() {
        const containerElem = this.container.nativeElement;
        this.oktaSignInWidget.renderEl(
          { el: containerElem },
          response => {}, // success callback
          error => {} // error callback 
        );
      }
    
      ngOnDestroy() {
        if (this.oktaSignInWidget) {
          this.oktaSignInWidget.remove();
          this.oktaSignInWidget = null;
        }
      }
    }
    

    您应该将域的基本配置和其他环境特定数据移动到一个特殊文件 (environment.ts),例如 here

    如果在登录尝试后发生任何有意义的事情,您应该创建一个服务来处理身份验证状态并将(转换后的)结果委托给它。

    【讨论】:

      猜你喜欢
      • 2011-11-06
      • 2018-08-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-15
      • 2021-11-24
      • 2015-05-31
      • 2018-02-20
      相关资源
      最近更新 更多