{"action":"created","issue":{"url":"https://api.github.com/repos/angular/angular/issues/2014","labels_url":"https://api.github.com/repos/angular/angular/issues/2014/labels{/name}","comments_url":"https://api.github.com/repos/angular/angular/issues/2014/comments","events_url":"https://api.github.com/repos/angular/angular/issues/2014/events","html_url":"https://github.com/angular/angular/issues/2014","id":78250227,"number":2014,"title":"Have a schema for bindings, and report error on miss-typed bindings.","user":{"login":"mhevery","id":111951,"avatar_url":"https://avatars.githubusercontent.com/u/111951?v=3","gravatar_id":"","url":"https://api.github.com/users/mhevery","html_url":"https://github.com/mhevery","followers_url":"https://api.github.com/users/mhevery/followers","following_url":"https://api.github.com/users/mhevery/following{/other_user}","gists_url":"https://api.github.com/users/mhevery/gists{/gist_id}","starred_url":"https://api.github.com/users/mhevery/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mhevery/subscriptions","organizations_url":"https://api.github.com/users/mhevery/orgs","repos_url":"https://api.github.com/users/mhevery/repos","events_url":"https://api.github.com/users/mhevery/events{/privacy}","received_events_url":"https://api.github.com/users/mhevery/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/angular/angular/labels/comp:%20core/view","name":"comp: core/view","color":"c7def8"},{"url":"https://api.github.com/repos/angular/angular/labels/effort2:%20medium%20(day)","name":"effort2: medium (day)","color":"bfe5bf"},{"url":"https://api.github.com/repos/angular/angular/labels/hotlist:%20beta","name":"hotlist: beta","color":"d4c5f9"},{"url":"https://api.github.com/repos/angular/angular/labels/P1:%20urgent","name":"P1: urgent","color":"eb6420"},{"url":"https://api.github.com/repos/angular/angular/labels/type:%20feature","name":"type: feature","color":"EEEEEE"}],"state":"open","locked":false,"assignee":{"login":"pkozlowski-opensource","id":973550,"avatar_url":"https://avatars.githubusercontent.com/u/973550?v=3","gravatar_id":"","url":"https://api.github.com/users/pkozlowski-opensource","html_url":"https://github.com/pkozlowski-opensource","followers_url":"https://api.github.com/users/pkozlowski-opensource/followers","following_url":"https://api.github.com/users/pkozlowski-opensource/following{/other_user}","gists_url":"https://api.github.com/users/pkozlowski-opensource/gists{/gist_id}","starred_url":"https://api.github.com/users/pkozlowski-opensource/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pkozlowski-opensource/subscriptions","organizations_url":"https://api.github.com/users/pkozlowski-opensource/orgs","repos_url":"https://api.github.com/users/pkozlowski-opensource/repos","events_url":"https://api.github.com/users/pkozlowski-opensource/events{/privacy}","received_events_url":"https://api.github.com/users/pkozlowski-opensource/received_events","type":"User","site_admin":false},"milestone":{"url":"https://api.github.com/repos/angular/angular/milestones/41","html_url":"https://github.com/angular/angular/milestones/alpha-33","labels_url":"https://api.github.com/repos/angular/angular/milestones/41/labels","id":1205895,"number":41,"title":"alpha-33","description":"Closing milestone.  Work on all issues to complete by Monday July 27 @ 8am PT; sync internal/external by July 29 EOD.","creator":{"login":"naomiblack","id":2286589,"avatar_url":"https://avatars.githubusercontent.com/u/2286589?v=3","gravatar_id":"","url":"https://api.github.com/users/naomiblack","html_url":"https://github.com/naomiblack","followers_url":"https://api.github.com/users/naomiblack/followers","following_url":"https://api.github.com/users/naomiblack/following{/other_user}","gists_url":"https://api.github.com/users/naomiblack/gists{/gist_id}","starred_url":"https://api.github.com/users/naomiblack/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/naomiblack/subscriptions","organizations_url":"https://api.github.com/users/naomiblack/orgs","repos_url":"https://api.github.com/users/naomiblack/repos","events_url":"https://api.github.com/users/naomiblack/events{/privacy}","received_events_url":"https://api.github.com/users/naomiblack/received_events","type":"User","site_admin":false},"open_issues":9,"closed_issues":37,"state":"open","created_at":"2015-07-13T20:39:21Z","updated_at":"2015-07-28T15:29:00Z","due_on":"2015-07-27T07:00:00Z","closed_at":null},"comments":18,"created_at":"2015-05-19T21:06:03Z","updated_at":"2015-07-28T15:34:51Z","closed_at":null,"body":"Quick, can you spot an error? (Currently it fails silently.)\r\n\r\n```html\r\n<ul>\r\n  <li *ng-for=\"item in items\">{{item}}</li>\r\n</ul>\r\n```\r\nThere are two issues:\r\n- It is `for of` not `for in`\r\n- It needs `var item` or `#item` instead of `item`\r\n\r\nThe current binding expands to \r\n\r\n```html\r\n<ul>\r\n  <template [ng-for]=\"item\" [ng-for-in]=\"items\">\r\n    <li>{{item}}</li>\r\n  </template>\r\n</ul>\r\n```\r\n\r\nbut it should have been:\r\n\r\n```html\r\n<ul>\r\n  <template ng-for #item [ng-for-of]=\"items\">\r\n    <li>{{item}}</li>\r\n  </template>\r\n</ul>\r\n```\r\n\r\n\r\n- [x] 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 have `ngFor` or `ngForOf` and hence should have prevent the monkey patch)\r\n- [ ] it then fails to notice that `item` is not defined (because we are trying to define it) (This should have failed!)\r\n\r\n# GOAL\r\n- Identify typos in the HTML bindings and throw errors to hint to developers.\r\n\r\n# Strategy\r\n\r\nThe 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.\r\n\r\n```html\r\n<div [title]=\"exp\"></div>\r\n<svg>\r\n  <g [x]=\"exp\">\r\n<svg>\r\n```\r\n\r\nWe 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:\r\n\r\n```\r\nvar schema = {\r\n  'div': { 'title': 'title' },\r\n  'svg:g': { 'x': '@x' }\r\n}\r\n```\r\n\r\nThe 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'}` )\r\n\r\nWe 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. \r\n\r\nBut 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.\r\n\r\n```html\r\n<google-youtube [video-id]=\"exp\">\r\n```\r\n\r\nthere is no way for Angular to know if `videoId` is a valid, as a result we need to configure this:\r\n\r\n```javascript\r\n@View({\r\n  webComponents: {\r\n    'google-youtube': {'!extends': 'div', 'video-id': 'videoId'}\r\n  }\r\n})\r\n```\r\nNOTE: `!extends` is used to say that all mappings from the `div` should be included.\r\n\r\nBy adding this schema definition Angular will be able to correctly resolve web-component assignments.\r\n\r\n# Resolution Rules\r\n\r\n```html\r\n<div [foo]=\"exp\" bar=\"literal\">\r\n```\r\n\r\n1. `foo` (property binding)\r\n  - Is in schema => then assign `foo` property to element\r\n  - is in schema and is a directive => assign to `foo` property and to the directive\r\n  - is not in schema but it has a directive => assign to directive only\r\n  - is not in schema and does not have a directive => Throw an error\r\n2. `bar` (just a literal)\r\n  - Is in schema => no-op (we leave the property as is)\r\n  - is in schema and is a directive => assign the literal one-time to the directive\r\n  - is not in schema but it has a directive => assign the literal one-time to the directive\r\n  - 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.)\r\n\r\n\r\n# Error handling.\r\n\r\nWith the above rules the example will produce these errors:\r\n\r\n```html\r\n<ul>\r\n  <li *ng-for=\"item in items\">{{item}}</li>\r\n</ul>\r\n```\r\n\r\n```html\r\n<ul>\r\n  <template [ng-for]=\"item\" [ng-for-in]=\"items\">\r\n    <li>{{item}}</li>\r\n  </template>\r\n</ul>\r\n```\r\n\r\n\r\n* `Can not bind 'item' to 'ng-for' because 'ng-for' is not a property of [TemplateElement, NgFor].`\r\n* `Can not bind `items` to 'ng-for-in' because 'ng-for' is not property of [TemplateElement, NgFor].`\r\n\r\n"},"comment":{"url":"https://api.github.com/repos/angular/angular/issues/comments/125656018","html_url":"https://github.com/angular/angular/issues/2014#issuecomment-125656018","issue_url":"https://api.github.com/repos/angular/angular/issues/2014","id":125656018,"user":{"login":"pkozlowski-opensource","id":973550,"avatar_url":"https://avatars.githubusercontent.com/u/973550?v=3","gravatar_id":"","url":"https://api.github.com/users/pkozlowski-opensource","html_url":"https://github.com/pkozlowski-opensource","followers_url":"https://api.github.com/users/pkozlowski-opensource/followers","following_url":"https://api.github.com/users/pkozlowski-opensource/following{/other_user}","gists_url":"https://api.github.com/users/pkozlowski-opensource/gists{/gist_id}","starred_url":"https://api.github.com/users/pkozlowski-opensource/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pkozlowski-opensource/subscriptions","organizations_url":"https://api.github.com/users/pkozlowski-opensource/orgs","repos_url":"https://api.github.com/users/pkozlowski-opensource/repos","events_url":"https://api.github.com/users/pkozlowski-opensource/events{/privacy}","received_events_url":"https://api.github.com/users/pkozlowski-opensource/received_events","type":"User","site_admin":false},"created_at":"2015-07-28T15:34:51Z","updated_at":"2015-07-28T15:34:51Z","body":"I'm almost here, working on plugging the registry into the whole system. Not sure if we will be able to land  #3225 today. \r\n\r\n@mhevery @tbosch could we have a quick chat today about steps to make it fully work for Dart?"}}