From e8d2348e21d8eb8adf2bb222b1ff9c7b6fab80a0 Mon Sep 17 00:00:00 2001 From: profanis Date: Sat, 5 Sep 2020 19:09:00 +0300 Subject: [PATCH] docs: how to create a custom Attribute decorator in a child component and use it from a parent component (#38721) Aside from using the @input() decorator, we can use the @Attrbitute decorator too. Of course, those two are different and support different causes. I expected to see a working example on the Attribute Bindings section, but I didn't find one. This PR depicts the usage of the Attribute decorator between two components PR Close #38721 --- .../src/app/app.component.html | 4 +- .../attribute-binding/src/app/app.module.ts | 6 +- ...nput-with-attribute-decorator.component.ts | 9 ++ aio/content/guide/attribute-binding.md | 106 ++++++++++++++++++ 4 files changed, 121 insertions(+), 4 deletions(-) create mode 100644 aio/content/examples/attribute-binding/src/app/my-input-with-attribute-decorator.component.ts diff --git a/aio/content/examples/attribute-binding/src/app/app.component.html b/aio/content/examples/attribute-binding/src/app/app.component.html index 7514b871c1..5429ce21c2 100644 --- a/aio/content/examples/attribute-binding/src/app/app.component.html +++ b/aio/content/examples/attribute-binding/src/app/app.component.html @@ -66,4 +66,6 @@ - + + + diff --git a/aio/content/examples/attribute-binding/src/app/app.module.ts b/aio/content/examples/attribute-binding/src/app/app.module.ts index 82bb10d175..c835fc16cb 100644 --- a/aio/content/examples/attribute-binding/src/app/app.module.ts +++ b/aio/content/examples/attribute-binding/src/app/app.module.ts @@ -1,15 +1,15 @@ import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; - import { AppComponent } from './app.component'; import { CompWithHostBindingComponent } from './comp-with-host-binding.component'; - +import { MyInputWithAttributeDecoratorComponent } from './my-input-with-attribute-decorator.component'; @NgModule({ declarations: [ AppComponent, - CompWithHostBindingComponent + CompWithHostBindingComponent, + MyInputWithAttributeDecoratorComponent ], imports: [ BrowserModule diff --git a/aio/content/examples/attribute-binding/src/app/my-input-with-attribute-decorator.component.ts b/aio/content/examples/attribute-binding/src/app/my-input-with-attribute-decorator.component.ts new file mode 100644 index 0000000000..9a08650168 --- /dev/null +++ b/aio/content/examples/attribute-binding/src/app/my-input-with-attribute-decorator.component.ts @@ -0,0 +1,9 @@ +import { Attribute, Component } from '@angular/core'; + +@Component({ + selector: 'app-my-input-with-attribute-decorator', + template: 'The type of the input is: {{ type }}' +}) +export class MyInputWithAttributeDecoratorComponent { + constructor(@Attribute('type') public type: string) { } +} diff --git a/aio/content/guide/attribute-binding.md b/aio/content/guide/attribute-binding.md index 5affacd929..c89eef98a0 100644 --- a/aio/content/guide/attribute-binding.md +++ b/aio/content/guide/attribute-binding.md @@ -248,3 +248,109 @@ The following table summarizes style binding syntax. ['width', '100px'] + +The [NgStyle](guide/built-in-directives/#ngstyle) directive can be used as an alternative to direct `[style]` bindings. +However, using the above style binding syntax without `NgStyle` is preferred because due to improvements in style binding in Angular, `NgStyle` no longer provides significant value, and might eventually be removed in the future. + + +
+ +{@a styling-precedence} + +## Styling Precedence + +A single HTML element can have its CSS class list and style values bound to multiple sources (for example, host bindings from multiple directives). + +When there are multiple bindings to the same class name or style property, Angular uses a set of precedence rules to resolve conflicts and determine which classes or styles are ultimately applied to the element. + +
+

Styling precedence (highest to lowest)

+ +1. Template bindings + 1. Property binding (for example, `
` or `
`) + 1. Map binding (for example, `
` or `
`) + 1. Static value (for example, `
` or `
`) +1. Directive host bindings + 1. Property binding (for example, `host: {'[class.foo]': 'hasFoo'}` or `host: {'[style.color]': 'color'}`) + 1. Map binding (for example, `host: {'[class]': 'classExpr'}` or `host: {'[style]': 'styleExpr'}`) + 1. Static value (for example, `host: {'class': 'foo'}` or `host: {'style': 'color: blue'}`) +1. Component host bindings + 1. Property binding (for example, `host: {'[class.foo]': 'hasFoo'}` or `host: {'[style.color]': 'color'}`) + 1. Map binding (for example, `host: {'[class]': 'classExpr'}` or `host: {'[style]': 'styleExpr'}`) + 1. Static value (for example, `host: {'class': 'foo'}` or `host: {'style': 'color: blue'}`) + +
+ +The more specific a class or style binding is, the higher its precedence. + +A binding to a specific class (for example, `[class.foo]`) will take precedence over a generic `[class]` binding, and a binding to a specific style (for example, `[style.bar]`) will take precedence over a generic `[style]` binding. + + + +Specificity rules also apply when it comes to bindings that originate from different sources. +It's possible for an element to have bindings in the template where it's declared, from host bindings on matched directives, and from host bindings on matched components. + +Template bindings are the most specific because they apply to the element directly and exclusively, so they have the highest precedence. + +Directive host bindings are considered less specific because directives can be used in multiple locations, so they have a lower precedence than template bindings. + +Directives often augment component behavior, so host bindings from components have the lowest precedence. + + + +In addition, bindings take precedence over static attributes. + +In the following case, `class` and `[class]` have similar specificity, but the `[class]` binding will take precedence because it is dynamic. + + + +{@a styling-delegation} +### Delegating to styles with lower precedence + +It is possible for higher precedence styles to "delegate" to lower precedence styles using `undefined` values. +Whereas setting a style property to `null` ensures the style is removed, setting it to `undefined` will cause Angular to fall back to the next-highest precedence binding to that style. + +For example, consider the following template: + + + +Imagine that the `dirWithHostBinding` directive and the `comp-with-host-binding` component both have a `[style.width]` host binding. +In that case, if `dirWithHostBinding` sets its binding to `undefined`, the `width` property will fall back to the value of the `comp-with-host-binding` host binding. +However, if `dirWithHostBinding` sets its binding to `null`, the `width` property will be removed entirely. + + +
+ +## Injecting attribute values + +There are cases where you need to differentiate the behavior of a [Component](api/core/Component) or [Directive](api/core/Directive) based on a static value set on the host element as an HTML attribute. For example, you might have a directive that needs to know the `type` of a `