Repository navigation
Description
Quick, can you spot an error? (Currently it fails silently.)
<ul>
<li *ng-for="item in items">{{item}}</li>
</ul>There are two issues:
- It is
for ofnotfor in - It needs
var itemor#iteminstead ofitem
The current binding expands to
<ul>
<template [ng-for]="item" [ng-for-in]="items">
<li>{{item}}</li>
</template>
</ul>but it should have been:
<ul>
<template ng-for #item [ng-for-of]="items">
<li>{{item}}</li>
</template>
</ul>- it fails to match
[ng-for][ng-for-of]and turns the binding to element property bindings (ie monkey patches the properties on template element) (This should have failed because it should have noticed that the element does not havengFororngForOfand hence should have prevent the monkey patch) - it then fails to notice that
itemis not defined (because we are trying to define it) (This should have failed!)
GOAL
- Identify typos in the HTML bindings and throw errors to hint to developers.
Strategy
The way to do this properly is to have a schema for which properties are allowed on which DOM elements. Currently we can lazy compute such as schema for DOM elements. But we can not compute them for WebComponents. So the proposal is to WebComponents publish their own schema.
<div [title]="exp"></div>
<svg>
<g [x]="exp">
<svg>We can lazy compute that title is a property of div (by noticing that title is a property of the div element). This can be done in Compiler during the compilation step. The result would be something like:
var schema = {
'div': { 'title': 'title' },
'svg:g': { 'x': '@x' }
}
The above would tell us that it is OK to bind to title to internal property name title on a div. (We need this as some properties don't properly rename see { 'inner-html': 'innerHTML', 'readonly': 'readOnly', 'tabindex': 'tabIndex'} )
We could also tell that g is instance of SVGElement and in that case we bind to the x attribute rather then the default x properties.
But this does not work with WebComponents because during the compilation the element is in template tag and is not active, as a result we can not query its properties.
<google-youtube [video-id]="exp">there is no way for Angular to know if videoId is a valid, as a result we need to configure this:
@View({
webComponents: {
'google-youtube': {'!extends': 'div', 'video-id': 'videoId'}
}
})NOTE: !extends is used to say that all mappings from the div should be included.
By adding this schema definition Angular will be able to correctly resolve web-component assignments.
Resolution Rules
<div [foo]="exp" bar="literal">foo(property binding)- Is in schema => then assign
fooproperty to element - is in schema and is a directive => assign to
fooproperty and to the directive - is not in schema but it has a directive => assign to directive only
- is not in schema and does not have a directive => Throw an error
- Is in schema => then assign
bar(just a literal)- Is in schema => no-op (we leave the property as is)
- is in schema and is a directive => assign the literal one-time to the directive
- is not in schema but it has a directive => assign the literal one-time to the directive
- is not in schema and does not have a directive => Throw an error. (Implication is that if a component wants to use attributes for CSS which are not part of DOM, they will have to be declared ahead of time in the schema.)
Error handling.
With the above rules the example will produce these errors:
<ul>
<li *ng-for="item in items">{{item}}</li>
</ul><ul>
<template [ng-for]="item" [ng-for-in]="items">
<li>{{item}}</li>
</template>
</ul>Can not bind 'item' to 'ng-for' because 'ng-for' is not a property of [TemplateElement, NgFor].Can not binditemsto 'ng-for-in' because 'ng-for' is not property of [TemplateElement, NgFor].
Activity
ewinslow commentedon May 20, 2015
Thanks for working on this, Misko! This is really the first developer-happiness-related issue I noticed when I tried out the dev preview, so glad to see it is being addressed and thought about. I like the idea of being able to declare schemas. Do we also need to be able to declare exposed events for the same reasons given?
There are a few more magic symbols introduced here which makes me a bit nervous. Can we try to avoid adding more symbols to the API? I'm speaking here of
@for "bind to attribute" and!extends. Symbols are asking to become "Angular WAT" material for sure...I'd also love to encourage more user-centered error messaging, if at all possible. The current error messages are better than nothing, but otherwise meaningless to me as a humble developer (you might also have some typos? If so, that's not helping either). What I'm looking for is something more straightforward like:
I realize that guessing developer intent is a bit hard to do in the general case, and I apologize for not having a ready suggestion to that end, but I suspect forgetting to use
#orvarto declare variables is going to be a rather common issue, so it'd be great to get the most helpful messages we can protecting developers against that pitfall.vicb commentedon Jun 2, 2015
@naomiblack Have you unassigned me by error or is someone else working on this ?
39 remaining items
pkozlowski-opensource commentedon Jul 28, 2015
I'm almost here, working on plugging the registry into the whole system. Not sure if we will be able to land #3225 today.
@mhevery @tbosch could we have a quick chat today about steps to make it fully work for Dart?
pkozlowski-opensource commentedon Jul 29, 2015
@mhevery so, we've got already functionality for detecting missing bindings and the initial schema support landed via d894aa9.
I think that it is time to replace this big issue with smaller, more-focused ones:
I can propose / open those issues and run them through you.
pkozlowski-opensource commentedon Jul 31, 2015
@mhevery With basic schema support done in d894aa9 I've opened smaller and focused issues to add missing pieces of elements schema support:
Closing this one in favor of the newly opened issues, would be great if you could triage those to prioritize work on next steps.
angular-automatic-lock-bot commentedon Sep 6, 2019
This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.
Read more about our automatic conversation locking policy.
This action has been performed automatically by a bot.