什么是渲染器适配器?
What is the RendererAdapter?
虽然我无法重现问题,但请看看我的 plunker。
当我尝试在我的本地工作区中打开对话框时收到以下错误:
ERROR TypeError: this._renderer.setProperty is not a function
at NgbRadio.set [as value] (radio.js:133)
at updateProp (core.es5.js:11160)
at checkAndUpdateDirectiveInline (core.es5.js:10852)
at checkAndUpdateNodeInline (core.es5.js:12382)
at checkAndUpdateNode (core.es5.js:12321)
at debugCheckAndUpdateNode (core.es5.js:13180)
at debugCheckDirectivesFn (core.es5.js:13121)
at Object.eval [as updateDirectives] (AdEditorComponent.html:48)
at Object.debugUpdateDirectives [as updateDirectives] (core.es5.js:13106)
at checkAndUpdateView (core.es5.js:12288)
我测试了许多较小的案例,然后发现 RendererAdapter 在 NgbRadio 组件中包含有效的 DebugRenderer2 实例。
所以,我写了一个 hack 到 NgbRadio 和 NgbActiveLabel 的构造函数中进行测试,然后应用程序工作正常:
this._renderer = _renderer.constructor.name === 'RendererAdapter'? _renderer.delegate: _renderer;
而模板中的这个结构出错:
<div [ngSwitch]="conditionalProperty">
<my-component *ngSwitchCase="'case1'" ...></my-component>
<my-another-comp *ngSwitchCase="'case2'" ...></my-another-comp>
</div>
让我列出对话框可以在我的本地打开的两种情况:
- 不要将任何管道依赖项(他们不关心管道是我自定义的还是@angular/common提供的)注入模板中具有 ngSwitchCase 属性的组件
- ngSwitch 中只有一个组件 div(但可以包含其他正常的 div 具有 ngSwitchCase)
我测试了最新版本的 Chrome、Safari 和 Firefox,我的 angular 版本是 4.2.4。
我在 Google 中找不到任何关于 RendererAdapter 的有用文章。
我可能会使用上面的 hack 来解决这个问题,但不想忽略真正的问题。如果有任何答案,我将不胜感激。
现在的默认渲染器是 Renderer2。因此,当您将渲染器注入组件时,您应该使用 Renderer2
token:
class MyComponent {
constructor(renderer: Renderer2)
但是,Angular 的早期版本使用了现在已弃用的 Renderer 并注入它 Renderer
使用了令牌:
class MyComponent {
constructor(renderer: Renderer)
RendererAdapter
是一个class,将旧的API映射到新的API,例如,第一个渲染器有listenGlobal
方法,而后者API 使用 listen
。这是此特定方法的映射:
listenGlobal(target: string, name: string, callback: Function): Function {
return this.delegate.listen(target, name, <any>callback);
}
其中委托是 Renderer2
的一个实例。
如果您不使用 Renderer
注入令牌,则不会创建 RendererAdapter
。 ngbRadio
的版本可能使用旧的渲染器。当前版本 seem to be using new renderer.
另见
虽然我无法重现问题,但请看看我的 plunker。
当我尝试在我的本地工作区中打开对话框时收到以下错误:
ERROR TypeError: this._renderer.setProperty is not a function
at NgbRadio.set [as value] (radio.js:133)
at updateProp (core.es5.js:11160)
at checkAndUpdateDirectiveInline (core.es5.js:10852)
at checkAndUpdateNodeInline (core.es5.js:12382)
at checkAndUpdateNode (core.es5.js:12321)
at debugCheckAndUpdateNode (core.es5.js:13180)
at debugCheckDirectivesFn (core.es5.js:13121)
at Object.eval [as updateDirectives] (AdEditorComponent.html:48)
at Object.debugUpdateDirectives [as updateDirectives] (core.es5.js:13106)
at checkAndUpdateView (core.es5.js:12288)
我测试了许多较小的案例,然后发现 RendererAdapter 在 NgbRadio 组件中包含有效的 DebugRenderer2 实例。
所以,我写了一个 hack 到 NgbRadio 和 NgbActiveLabel 的构造函数中进行测试,然后应用程序工作正常:
this._renderer = _renderer.constructor.name === 'RendererAdapter'? _renderer.delegate: _renderer;
而模板中的这个结构出错:
<div [ngSwitch]="conditionalProperty">
<my-component *ngSwitchCase="'case1'" ...></my-component>
<my-another-comp *ngSwitchCase="'case2'" ...></my-another-comp>
</div>
让我列出对话框可以在我的本地打开的两种情况:
- 不要将任何管道依赖项(他们不关心管道是我自定义的还是@angular/common提供的)注入模板中具有 ngSwitchCase 属性的组件
- ngSwitch 中只有一个组件 div(但可以包含其他正常的 div 具有 ngSwitchCase)
我测试了最新版本的 Chrome、Safari 和 Firefox,我的 angular 版本是 4.2.4。
我在 Google 中找不到任何关于 RendererAdapter 的有用文章。 我可能会使用上面的 hack 来解决这个问题,但不想忽略真正的问题。如果有任何答案,我将不胜感激。
现在的默认渲染器是 Renderer2。因此,当您将渲染器注入组件时,您应该使用 Renderer2
token:
class MyComponent {
constructor(renderer: Renderer2)
但是,Angular 的早期版本使用了现在已弃用的 Renderer 并注入它 Renderer
使用了令牌:
class MyComponent {
constructor(renderer: Renderer)
RendererAdapter
是一个class,将旧的API映射到新的API,例如,第一个渲染器有listenGlobal
方法,而后者API 使用 listen
。这是此特定方法的映射:
listenGlobal(target: string, name: string, callback: Function): Function {
return this.delegate.listen(target, name, <any>callback);
}
其中委托是 Renderer2
的一个实例。
如果您不使用 Renderer
注入令牌,则不会创建 RendererAdapter
。 ngbRadio
的版本可能使用旧的渲染器。当前版本 seem to be using new renderer.
另见