什么是RendererAdapter?

时间:2017-06-28 02:17:42

标签: angular ng-bootstrap

虽然我无法重现此问题,但请查看我的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实例。enter image description here

所以,我写了一个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,我的角度版本是4.2.4。

我找不到任何有关Google的RendererAdapter的有用文章。 我可能会使用上面的黑客来解决这个问题但不想忽视真正的问题。我很感激任何答案。

1 个答案:

答案 0 :(得分:0)

默认渲染器现在为Renderer2。因此,当您将渲染器注入组件时,应使用Renderer2标记:

class MyComponent {
   constructor(renderer: Renderer2)

但是,早期版本的Angular使用Renderer现已弃用并注入Renderer令牌:

class MyComponent {
   constructor(renderer: Renderer)

RendererAdapter是一个将旧API映射到新API的类,例如,第一个渲染器使用listenGlobal方法,而后一个API使用listen。以下是此特定方法的映射:

  listenGlobal(target: string, name: string, callback: Function): Function {
      return this.delegate.listen(target, name, <any>callback);
  }

其中delegate是Renderer2的实例。

如果您不使用Renderer注入令牌,则不会创建RendererAdapterngbRadio版本可能使用旧渲染器。当前版本seem to be using new renderer

另见