Angular 2: Is usage of Parentheses / Square brackets mandatory?
In fact, []
and ()
are valid HTML chars in attributes. If you generate HTML code on the server-side or use any other pre-processor that can't handle those characters, you can always use the equivalent canonical syntax.
[]
is a shorthand forbind-*
, hence[propertyName] == bind-property-name
()
is a shorthand foron-*
, hence(eventName) == on-event-name
This syntax is used mainly because of two reasons (and actually mandatory):
- Escaping - Element attributes need to be escaped. If you have an image tag with a dynamic
src
like this:<img src="{{imageSource}}">
this would result in a404
error, because the browser immediately tries to request the given URL. The URL in that particular moment is{{imageSource}}
which is for sure no valid URL. Therefore we have thengSrc
attribute in Angular 1. We can use it like<img ng-src="{{imageSource}}">
. What it does is, it waits until the interpolation is evaluated and then adds asrc
attribute the image. This ensures that no wrong request is made due to asynchronous interpolation evaluation. There are a couple of more directives that help out on this, likeng-href
. Now, when it comes to Web Components, attribute names are not deterministic anymore. Web Components can define their own attributes which the framework doesn't know about. So we have two options: we either create a directive for each attribute that needs escaping (oh noes!), or we come up with a more generic syntax that Angular understands and lets the framework intercept accordingly. This is why[propertyName]
has been introduced. Again, this is just a shortcut. Use the canonical syntax if that doesn't suite you. - Property Binding - Now you might wonder why
[propertyName]
and not[attributeName]
. It turns out that we come across a another problem when dealing with custom elements, that are not aware of Angular's directive lifecycle. In Angular, we could decide how a value is bound to an element's scope. So in this code:<my-directive foo="bar">
,bar
could be either just string, or an object that is two-way data bound. We only know that by looking into the directive's implementation. However, Web Components and Custom Elements simply don't know about Angular's lifecycle. Which means, an attribute value always a string, because that's what an attribute is in HTML. In order to make sure that we can still pass other values than just strings to any element, Angular 2 binds to element properties instead of attributes. Because a property on a DOM element's object can be anything, not just a string. So with[]
syntax, we also tell Angular that we do want to bind to the element's property, not it's attribute. This also means that now the consumer of a directive/element/webcomponent is in charge of deciding how a value is passed to it.
I've written an article about it that covers that topic, also there's a talk from ngeurope.
I hope this clears things up!
It's not mandatory - see here.
Please checkout the directives section (near the middle of the page): the "Decorator Directive" is still there, which means with regards to your question.
There will be a fall back way for sure.
Do checkout the official demonstration as well: ng-model
/click
are used in that as well.