Skip to content

Commit 3a3eaf0

Browse files
committed
Merge pull request rust-lang#24 from emberjs/attr-node
HTMLBars Bound Attributes
2 parents 9f046fd + 5dde5fe commit 3a3eaf0

File tree

1 file changed

+118
-0
lines changed

1 file changed

+118
-0
lines changed

active/0000-bound-attributes.md

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
- 2014-11-26
2+
- RFC PR:
3+
- Ember Issue:
4+
5+
# Summary
6+
7+
Unlike Handlebars, HTMLBars parses HTML as it parses a template.
8+
Bound attributes are one syntax now possible.
9+
10+
For example, this variable `color` is bound to set a class:
11+
12+
```hbs
13+
<div class="{{color}}"></div>
14+
```
15+
16+
Though traditional HTML attribute syntax should be preserved (using
17+
`class` and not `className` for example), the default path will be
18+
to set attributes as properties on the DOM node.
19+
20+
However this happy path has several important exceptions, and results
21+
in a few strange edge cases. This rfc will go into detail about the
22+
expected behavior without talking about the implementation of attribute
23+
on the Ember rendering pipeline.
24+
25+
# Motivation
26+
27+
`{{bind-attr` is a verbose syntax and difficult for new developers to
28+
understand.
29+
30+
# Detailed design
31+
32+
Given a use of bound attributes:
33+
34+
```hbs
35+
<input type="checkbox" checked={{isChecked}}>
36+
```
37+
38+
There are three important inputs:
39+
40+
* The element (`tagName`, `namespaceURI`)
41+
* The attribute name
42+
* The value (literal or stream)
43+
44+
The following described the algorithm for updating the attribute/property
45+
value on an element.
46+
47+
1. If the element has an SVG namespace, use `setAttribute`. Setting SVG attributes
48+
as properties is not supported.
49+
2. If the attribute name is `style`, use `setAttribute`.
50+
3. Normalize the property name as described in `propertyNameFor` below. If a normalized
51+
name is returned, set that property on the element (`element[normalizedPropName]`).
52+
If it is not returned, set with `setAttribute`.
53+
54+
`propertyNameFor` is a normalization setup for attribute names that takes the element
55+
and attribute name as input.
56+
57+
1. Build a list of normalized properties for the passed element `normalizedAttrs[element.tagName][elementAttrName.toLowerCase()] = elementAttrName`
58+
2. Fetch the normalized property name from this list `normalizedAttr = normalizedAttrs[element.tagName][passedAttrName.toLowerCase()]`
59+
3. Return this normalized attr. If an `attrName` is did not normalize to a property (for example `class`), null is returned
60+
61+
### Acknowledged edge cases
62+
63+
* Boolean attrs with blank string won't work like they would in HTML: `<input disabled="{{blankString}}">` would be false
64+
* Some selectors may not work as expected. `<input value="{{color}}">` will not result in a working `[value=red]` selector
65+
66+
# Drawbacks
67+
68+
None.
69+
70+
# Alternatives
71+
72+
Two obvious alternatives considered in detail are Angular and React.
73+
74+
In **Angular 2.0**, [a new prop/attr/event syntax](http://www.beyondjava.net/blog/angularjs-2-0-sneak-preview-data-binding/)
75+
is being introduced.
76+
77+
Setting an attribute just like setting an HTML attribute:
78+
79+
```html
80+
<pui-tab title="What a nice tab!">
81+
```
82+
83+
Properties are flagged with the `[]` syntax:
84+
85+
```html
86+
<input [disabled]="controller.isInputDisabled">
87+
```
88+
89+
Angular is limited by it's HTML templating here. The value must be quoted
90+
to have complex content, where as in HTMLBars it is easier to bend the
91+
rules to introduce literal values: `disabled={{controller.isInputDisabled}}`.
92+
93+
Events are out of our immediate purview in this RFC, but for completeness
94+
note Angular's syntax:
95+
96+
```html
97+
<button (click)="hide()">hide image</button>
98+
```
99+
100+
**React's JSX** has its own [property syntax](http://facebook.github.io/react/docs/jsx-in-depth.html),
101+
one that diverges from traditional HTML by focusing entirely on properties
102+
instead of attributes. This means the templates are well prepared for
103+
use with components, but also that JSX must maintain a large whitelist of
104+
special cases such as [supported tags](http://facebook.github.io/react/docs/tags-and-attributes.html)
105+
and [some HTML attributes](http://facebook.github.io/react/docs/jsx-gotchas.html).
106+
107+
In general we would prefer to have Ember templates be as close to HTML
108+
as possible, without requiring developers to learn a new set of property
109+
names replacing the attribute names they already know.
110+
111+
# Unresolved questions
112+
113+
* How do we deal with `on*` attributes?
114+
* Should we do anything special about generic element properties like `<div outerhtml={{lol}}></div>`?
115+
* Should HTMLBars unbound attributes use the same alorithm?
116+
117+
There is a spike of significant depth [in PR #9721](https://github.com/emberjs/ember.js/pull/9721)
118+
and a followup [in PR #9977](https://github.com/emberjs/ember.js/pull/9977).

0 commit comments

Comments
 (0)