Skip to content

Commit 222af38

Browse files
kapunahelewongkara
authored andcommitted
docs: move renderer2 deprecation guide into own file (angular#32626)
PR Close angular#32626
1 parent 73cb581 commit 222af38

3 files changed

Lines changed: 107 additions & 98 deletions

File tree

.github/CODEOWNERS

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -841,7 +841,7 @@ testing/** @angular/fw-test
841841
/aio/content/guide/updating.md @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
842842
/aio/content/guide/workspace-config.md @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
843843
/aio/content/guide/deprecations.md @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
844-
844+
/aio/content/guide/migration-renderer.md @angular/fw-docs-packaging @angular/framework-global-approvers @angular/framework-global-approvers-for-docs-only-changes
845845

846846

847847
# ================================================

aio/content/guide/deprecations.md

Lines changed: 10 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@ In a typical Angular project, the polyfill is not used in production builds, so
321321
{@a static-query-resolution}
322322
### `@ViewChild()` / `@ContentChild()` static resolution as the default
323323

324-
See our [dedicated migration guide for static queries](guide/static-query-migration).
324+
See the [dedicated migration guide for static queries](guide/static-query-migration).
325325

326326
{@a contentchild-input-together}
327327
### `@ContentChild()` / `@Input()` used together
@@ -389,6 +389,15 @@ As of Angular version 8, all `platform-webworker` APIs are deprecated.
389389
This includes both packages: `@angular/platform-webworker` and
390390
`@angular/platform-webworker-dynamic`.
391391

392+
393+
## Angular version 9 schematics
394+
395+
{@a renderer-to-renderer2}
396+
### Migrating from `Renderer` to `Renderer2`
397+
398+
See the [dedicated migration guide for Renderer](guide/migration-renderer).
399+
400+
392401
{@a removed}
393402
## Removed APIs
394403

@@ -464,99 +473,3 @@ For more information about using `@angular/common/http`, see the [HttpClient gui
464473
| --------------------- | ------------------------------------------- |
465474
| `MockBackend` | [`HttpTestingController`](/api/common/http/testing/HttpTestingController) |
466475
| `MockConnection` | [`HttpTestingController`](/api/common/http/testing/HttpTestingController) |
467-
468-
## Renderer to Renderer2 migration
469-
470-
The `Renderer` class has been marked as deprecated since Angular version 4 and is removed in Angular v9.
471-
472-
This section provides guidance on migrating from this deprecated API to the newer `Renderer2` API and what it means for your app.
473-
You can use the CLI `ng update` command or the [update tool](https://update.angular.io/) to perform the migration.
474-
475-
### Why should I migrate to Renderer2?
476-
477-
The deprecated `Renderer` class has been removed in version 9 of Angular, so it's necessary to migrate to a supported API. Using `Renderer2` is the recommended strategy because it supports a similar set of functionality to `Renderer`. The API surface is quite large (with 19 methods), but the schematic should simplify this process for your applications.
478-
479-
**Library authors** should definitely use this migration to move away from the `Renderer`. Otherwise, the libraries won't work with applications built with version 9.
480-
481-
### Is there action required on my end?
482-
483-
No. The `ng update` schematic should handle most cases with the exception of `Renderer.animate()` and `Renderer.setDebugInfo()`, which are not supported.
484-
485-
### What are the `__ngRendererX` methods? Why are they necessary?
486-
487-
Some methods either don't have exact equivalents in `Renderer2`, or they correspond to more than one expression. For example, both renderers have a `createElement()` method, but they're not equal because a call such as `renderer.createElement(parentNode, namespaceAndName)` in the `Renderer` corresponds to the following block of code in `Renderer2`:
488-
489-
```ts
490-
const [namespace, name] = splitNamespace(namespaceAndName);
491-
const el = renderer.createElement(name, namespace);
492-
if (parentNode) {
493-
renderer.appendChild(parentNode, el);
494-
}
495-
return el;
496-
```
497-
498-
Migration has to guarantee that the return values of functions and types of variables stay the same. To handle the majority of cases safely, the schematic declares helper functions at the bottom of the user's file. These helpers encapsulate your own logic and keep the replacements inside your code down to a single function call. Here's an example of how the `createElement()` migration looks:
499-
500-
501-
**Before:**
502-
503-
```ts
504-
public createAndAppendElement() {
505-
const el = this.renderer.createElement('span');
506-
el.textContent = 'hello world';
507-
return el;
508-
}
509-
```
510-
511-
**After:**
512-
513-
<code-example>
514-
515-
public createAndAppendElement() {
516-
const el = __ngRendererCreateElement(this.renderer, this.element, 'span');
517-
el.textContent = 'hello world';
518-
return el;
519-
}
520-
// Generated code at the bottom of the file
521-
__ngRendererCreateElement(renderer: any, parentNode: any, nameAndNamespace: any) {
522-
const [namespace, name] = __ngRendererSplitNamespace(namespaceAndName);
523-
const el = renderer.createElement(name, namespace);
524-
if (parentNode) {
525-
renderer.appendChild(parentNode, el);
526-
}
527-
return el;
528-
}
529-
__ngRendererSplitNamespace(nameAndNamespace: any) {
530-
// returns the split name and namespace
531-
}
532-
533-
</code-example>
534-
535-
When implementing these helper functions, the schematic ensures that they're only declared once per file and that their names are unique enough that there's a small chance of colliding with pre-existing functions in your code. The schematic also keeps their parameter types as `any` so that it doesn't have to insert extra logic that ensures that their values have the correct type.
536-
537-
538-
### Full list of method migrations
539-
540-
The following table shows all methods that the migration maps from `Renderer` to `Renderer2`.
541-
542-
|Renderer|Renderer2|
543-
|---|---|
544-
|`listen(renderElement, name, callback)`|`listen(renderElement, name, callback)`|
545-
|`setElementProperty(renderElement, propertyName, propertyValue)`|`setProperty(renderElement, propertyName, propertyValue)`|
546-
|`setText(renderNode, text)`|`setValue(renderNode, text)`|
547-
|`listenGlobal(target, name, callback)`|`listen(target, name, callback)`|
548-
|`selectRootElement(selectorOrNode, debugInfo?)`|`selectRootElement(selectorOrNode)`|
549-
|`createElement(parentElement, name, debugInfo?)`|`appendChild(parentElement, createElement(name))`|
550-
|`setElementStyle(el, style, value?)`|`value == null ? removeStyle(el, style) : setStyle(el, style, value)`
551-
|`setElementAttribute(el, name, value?)`|`attributeValue == null ? removeAttribute(el, name) : setAttribute(el, name, value)`
552-
|`createText(parentElement, value, debugInfo?)`|`appendChild(parentElement, createText(value))`|
553-
|`createTemplateAnchor(parentElement)`|`appendChild(parentElement, createComment(''))`|
554-
|`setElementClass(renderElement, className, isAdd)`|`isAdd ? addClass(renderElement, className) : removeClass(renderElement, className)`|
555-
|`projectNodes(parentElement, nodes)`|`for (let i = 0; i < nodes.length; i<ins></ins>) { appendChild(parentElement, nodes<i>); }`|
556-
|`attachViewAfter(node, viewRootNodes)`|`const parentElement = parentNode(node); const nextSibling = nextSibling(node); for (let i = 0; i < viewRootNodes.length; i<ins></ins>) { insertBefore(parentElement, viewRootNodes<i>, nextSibling);}`|
557-
|`detachView(viewRootNodes)`|`for (let i = 0; i < viewRootNodes.length; i<ins></ins>) {const node = viewRootNodes<i>; const parentElement = parentNode(node); removeChild(parentElement, node);}`|
558-
|`destroyView(hostElement, viewAllNodes)`|`for (let i = 0; i < viewAllNodes.length; i<ins></ins>) { destroyNode(viewAllNodes<i>); }`|
559-
|`setBindingDebugInfo()`|This function is a noop in `Renderer2`.|
560-
|`createViewRoot(hostElement)`|Should be replaced with a reference to `hostElement`|
561-
|`invokeElementMethod(renderElement, methodName, args?)`|`(renderElement as any)<methodName>.apply(renderElement, args);`|
562-
|`animate(element, startingStyles, keyframes, duration, delay, easing, previousPlayers?)`|Throws an error (same behavior as `Renderer.animate()`)|
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
# `Renderer` to `Renderer2` migration
2+
3+
## Migration Overview
4+
5+
The `Renderer` class has been marked as deprecated since Angular version 4. This section provides guidance on migrating from this deprecated API to the newer `Renderer2` API and what it means for your app.
6+
7+
## Why should I migrate to Renderer2?
8+
9+
The deprecated `Renderer` class has been removed in version 9 of Angular, so it's necessary to migrate to a supported API. Using `Renderer2` is the recommended strategy because it supports a similar set of functionality to `Renderer`. The API surface is quite large (with 19 methods), but the schematic should simplify this process for your applications.
10+
11+
## Is there action required on my end?
12+
13+
No. The schematic should handle most cases with the exception of `Renderer.animate()` and `Renderer.setDebugInfo()`, which already aren’t supported.
14+
15+
## What are the `__ngRendererX` methods? Why are they necessary?
16+
17+
Some methods either don't have exact equivalents in `Renderer2`, or they correspond to more than one expression. For example, both renderers have a `createElement()` method, but they're not equal because a call such as `renderer.createElement(parentNode, namespaceAndName)` in the `Renderer` corresponds to the following block of code in `Renderer2`:
18+
19+
```ts
20+
const [namespace, name] = splitNamespace(namespaceAndName);
21+
const el = renderer.createElement(name, namespace);
22+
if (parentNode) {
23+
renderer.appendChild(parentNode, el);
24+
}
25+
return el;
26+
```
27+
28+
Migration has to guarantee that the return values of functions and types of variables stay the same. To handle the majority of cases safely, the schematic declares helper functions at the bottom of the user's file. These helpers encapsulate your own logic and keep the replacements inside your code down to a single function call. Here's an example of how the `createElement()` migration looks:
29+
30+
31+
**Before:**
32+
33+
```ts
34+
public createAndAppendElement() {
35+
const el = this.renderer.createElement('span');
36+
el.textContent = 'hello world';
37+
return el;
38+
}
39+
```
40+
41+
**After:**
42+
43+
<code-example>
44+
45+
public createAndAppendElement() {
46+
const el = __ngRendererCreateElement(this.renderer, this.element, 'span');
47+
el.textContent = 'hello world';
48+
return el;
49+
}
50+
// Generated code at the bottom of the file
51+
__ngRendererCreateElement(renderer: any, parentNode: any, nameAndNamespace: any) {
52+
const [namespace, name] = __ngRendererSplitNamespace(namespaceAndName);
53+
const el = renderer.createElement(name, namespace);
54+
if (parentNode) {
55+
renderer.appendChild(parentNode, el);
56+
}
57+
return el;
58+
}
59+
__ngRendererSplitNamespace(nameAndNamespace: any) {
60+
// returns the split name and namespace
61+
}
62+
63+
</code-example>
64+
65+
When implementing these helper functions, the schematic ensures that they're only declared once per file and that their names are unique enough that there's a small chance of colliding with pre-existing functions in your code. The schematic also keeps their parameter types as `any` so that it doesn't have to insert extra logic that ensures that their values have the correct type.
66+
67+
### I’m a library author. Should I run this migration?
68+
69+
**Library authors should definitely use this migration to move away from the `Renderer`. Otherwise, the libraries won't work with applications built with version 9.**
70+
71+
72+
### Full list of method migrations
73+
74+
The following table shows all methods that the migration maps from `Renderer` to `Renderer2`.
75+
76+
|Renderer|Renderer2|
77+
|---|---|
78+
|`listen(renderElement, name, callback)`|`listen(renderElement, name, callback)`|
79+
|`setElementProperty(renderElement, propertyName, propertyValue)`|`setProperty(renderElement, propertyName, propertyValue)`|
80+
|`setText(renderNode, text)`|`setValue(renderNode, text)`|
81+
|`listenGlobal(target, name, callback)`|`listen(target, name, callback)`|
82+
|`selectRootElement(selectorOrNode, debugInfo?)`|`selectRootElement(selectorOrNode)`|
83+
|`createElement(parentElement, name, debugInfo?)`|`appendChild(parentElement, createElement(name))`|
84+
|`setElementStyle(el, style, value?)`|`value == null ? removeStyle(el, style) : setStyle(el, style, value)`
85+
|`setElementAttribute(el, name, value?)`|`attributeValue == null ? removeAttribute(el, name) : setAttribute(el, name, value)`
86+
|`createText(parentElement, value, debugInfo?)`|`appendChild(parentElement, createText(value))`|
87+
|`createTemplateAnchor(parentElement)`|`appendChild(parentElement, createComment(''))`|
88+
|`setElementClass(renderElement, className, isAdd)`|`isAdd ? addClass(renderElement, className) : removeClass(renderElement, className)`|
89+
|`projectNodes(parentElement, nodes)`|`for (let i = 0; i < nodes.length; i<ins></ins>) { appendChild(parentElement, nodes<i>); }`|
90+
|`attachViewAfter(node, viewRootNodes)`|`const parentElement = parentNode(node); const nextSibling = nextSibling(node); for (let i = 0; i < viewRootNodes.length; i<ins></ins>) { insertBefore(parentElement, viewRootNodes<i>, nextSibling);}`|
91+
|`detachView(viewRootNodes)`|`for (let i = 0; i < viewRootNodes.length; i<ins></ins>) {const node = viewRootNodes<i>; const parentElement = parentNode(node); removeChild(parentElement, node);}`|
92+
|`destroyView(hostElement, viewAllNodes)`|`for (let i = 0; i < viewAllNodes.length; i<ins></ins>) { destroyNode(viewAllNodes<i>); }`|
93+
|`setBindingDebugInfo()`|This function is a noop in `Renderer2`.|
94+
|`createViewRoot(hostElement)`|Should be replaced with a reference to `hostElement`|
95+
|`invokeElementMethod(renderElement, methodName, args?)`|`(renderElement as any)<methodName>.apply(renderElement, args);`|
96+
|`animate(element, startingStyles, keyframes, duration, delay, easing, previousPlayers?)`|Throws an error (same behavior as `Renderer.animate()`)|

0 commit comments

Comments
 (0)