angular - 实现操作 Dom 的第 3 方库的正确方法是什么?

标签 angular angular2-directives angular-renderer2

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

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

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

最佳答案

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

如果您使用选择器 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或文章 Using 3rd Party Library Inside Angular2通过 Netanel Basal(省略输入)我们可以进行如下操作:

要访问自定义组件中的元素,您应该让 Angular 注入(inject)对标记为 #container 的元素的引用,方法是添加一个用 ElementRef 修饰的类型属性@ViewChild('容器')

@ViewChild('container')
container: ElementRef;

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

在您的 View 初始化后,您应该让小部件实例将其自身渲染到容器元素中。请记住在组件被销毁时销毁小部件(可能通过调用 .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 .

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

关于angular - 实现操作 Dom 的第 3 方库的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53990204/

相关文章:

javascript - rxjs simple do http get 什么也不做

angular - 如何让 Mathjax 与 Angular2 一起工作?

angular - ngStyle VS 渲染器2?我应该使用什么?

javascript - Renderer2 错误 - id 与任何元素都不匹配

Angular 结构指令和 Renderer2

javascript - 如何在 ngOnInIt 函数中使用异步与 Angular8 firestore?

angular - 在Nginx Ingress AKS上设置Angular应用程序

angular - 将指令限制为Angular中的特定主机(组件)

Angular - 动态加载图像

angular - 如何仅在标签位于 `*ngIf=true` 时才初始化组件?