实现操纵Dom的第三方库的正确方法是什么?

Dou*_* S. 8 angular2-directives angular angular-renderer2

我正在使用第三方库将小部件渲染到屏幕上(Okta的SignInWidget).窗口小部件的呈现方式如下:

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

我最初的想法是把它放到一个指令中,但即使有指令你也应该让Renderer2进行渲染.这里有最好的做法吗?

Her*_*ers 6

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

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

<h1>Login</h1>
<p>Hi people, login to get more features:</p>
<myapp-login></myapp-login>
Run Code Online (Sandbox Code Playgroud)

大致遵循Angular大学的文章@ViewChild(简要提及第三方文库),这篇SO答案或Netanel Basal 使用第三方图书馆Angular2(省略输入)的文章我们可以按如下方式进行:

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

@ViewChild('container')
container: ElementRef;
Run Code Online (Sandbox Code Playgroud)

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

在视图初始化之后,您应该让窗口小部件实例将自身呈现到容器元素中.记得在组件被销毁时(可能通过调用.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;
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

您应该将域和其他特定于环境的数据的基本配置移动到特殊文件(environment.ts),就像这里一样.

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