实现操纵 Dom 的第 3 方库的正确方法是什么?
What is the right way to implement a 3rd party library that manipulates the Dom?
我正在使用第 3 方库将小部件呈现到屏幕上(Okta 的 SignInWidget)。 widget的渲染方式是这样的:
this.oktaSignInWidget.renderEl(
{ el: '#widget-container' },
() => {},
err => {
console.error(err);
}
);
我最初的想法是将其放入指令中,但即使使用指令,您也应该让 Renderer2 进行渲染。这里有最佳实践吗?
由于小部件可能 replaces/builds 给定容器的内容,这似乎是常规 Angular 组件的经典用例。
看来您也不需要动态实例化(通常在第 3 方库包含教程中找到)。
如果您使用选择器 myapp-login
创建组件,您可以将其放入您的某些登录页面:
<h1>Login</h1>
<p>Hi people, login to get more features:</p>
<myapp-login></myapp-login>
大致遵循 Netanel Basal 的 this Angular University's article about @ViewChild
(which briefly mentions third party libs too), or the article Using 3rd Party Library Inside Angular2(省略输入),我们可以进行如下操作:
要访问自定义组件中的元素,您应该让 Angular 通过添加 ElementRef
类型 属性 来注入对标记有 #container
的元素的引用] 饰以 @ViewChild('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.
如果在登录尝试后发生任何有意义的事情,您应该创建一个服务来处理身份验证状态并将(转换后的)结果委托给它。
我正在使用第 3 方库将小部件呈现到屏幕上(Okta 的 SignInWidget)。 widget的渲染方式是这样的:
this.oktaSignInWidget.renderEl(
{ el: '#widget-container' },
() => {},
err => {
console.error(err);
}
);
我最初的想法是将其放入指令中,但即使使用指令,您也应该让 Renderer2 进行渲染。这里有最佳实践吗?
由于小部件可能 replaces/builds 给定容器的内容,这似乎是常规 Angular 组件的经典用例。 看来您也不需要动态实例化(通常在第 3 方库包含教程中找到)。
如果您使用选择器 myapp-login
创建组件,您可以将其放入您的某些登录页面:
<h1>Login</h1>
<p>Hi people, login to get more features:</p>
<myapp-login></myapp-login>
大致遵循 Netanel Basal 的 this Angular University's article about @ViewChild
(which briefly mentions third party libs too),
要访问自定义组件中的元素,您应该让 Angular 通过添加 ElementRef
类型 属性 来注入对标记有 #container
的元素的引用] 饰以 @ViewChild('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.
如果在登录尝试后发生任何有意义的事情,您应该创建一个服务来处理身份验证状态并将(转换后的)结果委托给它。