-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implements RFC #60 (Component Unification) #11359
Conversation
|
||
state.manager = manager; | ||
if (!isTopLevel || tagName !== env.view.tagName) { | ||
var manager = ComponentNodeManager.create(renderNode, env, { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the use of var
here intentional? let
is used heavily elsewhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good catch!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not intentional; we were just moving around pre-existing code.
5d2c3fc
to
5a084f7
Compare
emberjs/rfcs#60 This commit implements the proposed semantics for angle-bracket components. The TLDR is that a component’s template represents its “outerHTML” rather than its “innerHTML”, which makes it easier to configure the element itself using templating constructs. Some salient points: 1. If there is a single root element, the attributes from the invocation are copied onto the root element. 2. The invocation’s attributes “win out” over the attributes from the root element in the component’s layout. 3. Classes are merged. If the invocation says `class=“a”` and the root element says `class=“b”`, the result is `class=“a b”`. The rationale is that when you say `class=“a”`, you are really saying “add the `a` class to this element”. A few sticky issues: 1. If the root element for the `my-foo` component is `<my-foo>`, we insert an element with tag name of `my-foo`. While this is intuitive, note that in all other cases, `<my-foo>` represents an invocation of the component. In the root position, that makes no sense, since it would inevitably produce a stack overflow. a. This “identity element” case makes it idiomatic to reflect the name of the component onto the DOM. b. Unfortunately, when we compile a template, we do not yet know what component that template is used for, and, indeed, whether it is even a template for a component at all. c. To capture the semantic differences, we do a bit of analysis at compile time (to determine *candidates* for top-level elements), and use runtime information (component invocation style and the name of the component looked up in the container) to disambiguate between a component’s element and an invocation of another component. 2. If the root element for the `my-foo` component is a regular HTML element, we use the `attachAttributes` functionality of HTMLBars to attach the attributes that the component was invoked with onto the root element. 3. In general, it is important that changes to attributes do not result in a change to the identity of the element that they are contained in. To achieve this, we reused much of the infrastructure built in `buildComponentTemplate`. The consequence of (1) and (2) above is that the semantics are always “a component’s layout represents its outerHTML”, even though the implementation is quite different depending on whether the root element is the same-named component or not.
5a084f7
to
e7866ca
Compare
We are going to get this merged behind a feature flag. We will work on removing support for the fragment case due to some concerns, and instead implement an error message if you do not provide a root element. |
Implements RFC #60 (Component Unification)
emberjs/rfcs#60
This commit implements the proposed semantics for angle-bracket
components. The TLDR is that a component’s template represents its
“outerHTML” rather than its “innerHTML”, which makes it easier to
configure the element itself using templating constructs.
Some salient points:
are copied onto the root element.
root element in the component’s layout.
class=“a”
and the rootelement says
class=“b”
, the result isclass=“a b”
. The rationaleis that when you say
class=“a”
, you are really saying “add thea
class to this element”.
A few sticky issues:
my-foo
component is<my-foo>
, weinsert an element with tag name of
my-foo
. While this is intuitive,note that in all other cases,
<my-foo>
represents an invocation ofthe component. In the root position, that makes no sense, since it
would inevitably produce a stack overflow.
a. This “identity element” case makes it idiomatic to reflect the
name of the component onto the DOM.
b. Unfortunately, when we compile a template, we do not yet know
what component that template is used for, and, indeed, whether it
is even a template for a component at all.
c. To capture the semantic differences, we do a bit of analysis at
compile time (to determine candidates for top-level elements),
and use runtime information (component invocation style and
the name of the component looked up in the container) to
disambiguate between a component’s element and an invocation of
another component.
my-foo
component is a regular HTMLelement, we use the
attachAttributes
functionality of HTMLBars toattach the attributes that the component was invoked with onto the
root element.
in a change to the identity of the element that they are contained
in. To achieve this, we reused much of the infrastructure built in
buildComponentTemplate
.The consequence of (1) and (2) above is that the semantics are always
“a component’s layout represents its outerHTML”, even though the
implementation is quite different depending on whether the root element
is the same-named component or not.