Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Wishlist: set properties of Custom Elements in templates #16235

Closed
2 tasks
vivainio opened this issue Sep 21, 2017 · 4 comments
Closed
2 tasks

Wishlist: set properties of Custom Elements in templates #16235

vivainio opened this issue Sep 21, 2017 · 4 comments

Comments

@vivainio
Copy link

vivainio commented Sep 21, 2017

I'm submitting a ...

  • bug report
  • [x ] feature request
  • other (Please do not submit support requests here (see above))

Current behavior:

Currently, you can't property bind HTMLElement properties in templates

Expected / new behavior:

If you have a custom element my-elem, you could property bind it to an expression:

<my-elem ng-prop-myprop="$ctrl.getComplexValue()"></my-elem>

ng.attr doesn't work for this because the value needs to be a string. Properties can be arbitrary complex JS object.

Minimal reproduction of the problem with instructions:

Currently you need to imperatively dig up the HTMLElement and assign the property in js code:

https://gist.github.com/vivainio/7025b4f5c1d90ab168981419f735d73a

AngularJS version: 1.6

Browser: [all | Chrome XX | Firefox XX | Edge XX | IE XX | Safari XX | Mobile Chrome XX | Android X.X Web Browser | iOS XX Safari | iOS XX UIWebView | iOS XX WKWebView ]

All.

Anything else:

Relevant blog post that illustrates the "clumsier" (imperative) way of doing this: https://medium.com/@vivainio/using-stenciljs-components-in-angular-1-application-2f09287c151

@Narretz
Copy link
Contributor

Narretz commented Sep 21, 2017

Hmm. That specifc format is definitely only possible inside $compile. However, you could write your own directive that binds a key value map to the element. That's a bit clumsier obviously but a more flexible workaround.

http://plnkr.co/edit/7gvw0cqICfYZFAPi6bcG

Here's a bit more info about the problems with an ngProp directive: #10072

Btw could you change "Angular 1" in your blog post to "AngularJS"? That's the preferred name. :)

@gkalpak
Copy link
Member

gkalpak commented Sep 21, 2017

It seems that there are valid security concerns with implementing this.
In the same spirit as @Narretz's plnkr, you can have a custom directive that looks very similar to what you want (but you take all the responsibility for using it securely 😛):

<my-elem ng-prop="myprop:$ctrl.getComplexValue()"></my-elem>

Demo

@vivainio
Copy link
Author

I'm not sure I understand what the security concerns in @Narretz plunkr approach are. The attributes that get assigned come from template, not variables / user input, so you can't assign to innerHtml unless innerHtml is one of the keys in the template.

@gkalpak
Copy link
Member

gkalpak commented Sep 23, 2017

First of all, there is no restrictions on where the expression comes from. The property names can be hard-code in the template, or be computed keys on the template, or the whole object can come from the controller (in which case it can be a result of user input).

Further more, by having a directive that can set any property, there is a lot of API surface to keep secure (innerHTML, src, onload, onerror, etc). Having this as a built-in directive, we can't rely on it being responsibly used. We would be providing a great opportunity for people to shoot themselves in the foot.

Having it as local directive, on the other hand, you will be responsible for using it securely. Which is much easier to do on a per project basis, because you can limit it to specific properties or otherwise ensure that it is not abused.

(That's my understanding at least 😁)

jbedard added a commit to jbedard/angular.js that referenced this issue Jul 30, 2018
…ings

Properties:

Previously only arbitrary DOM attribute bindings were supported via interpolation such as `my-attribute="{{expression}}"` or `ng-attr-my-attribute="{{expression}}"`, and only a set of distinct properties could be bound. `ng-prop-*` adds support for binding expressions to any DOM properties. For example `ng-prop-foo=”x”` will assign the value of the expression `x` to the `foo` property, and re-assign whenever the expression `x` changes.

Events:

Previously only a distinct set of DOM events could be bound using such as `ng-click`, `ng-blur` etc. `ng-on-*` adds support for binding expressions to any DOM event. For example `ng-on-bar=”barOccured($event)”` will add a listener to the “bar” event and invoke the `barOccured($event)` expression.

For properties or events using mixed case underscores can be used before capital letters. For example `ng-prop-my_prop="x"` will bind `x` to the `myProp` property, and `ng-on-my_custom_event="x()"` will invoke `x()` on the `myCustomEvent` event.

Fixes angular#16428
Fixes angular#16235
Closes angular#16614
jbedard added a commit to jbedard/angular.js that referenced this issue Jul 30, 2018
…ings

Properties:

Previously only arbitrary DOM attribute bindings were supported via interpolation such as
`my-attribute="{{expression}}"` or `ng-attr-my-attribute="{{expression}}"`, and only a set of
distinct properties could be bound. `ng-prop-*` adds support for binding expressions to any DOM
properties. For example `ng-prop-foo=”x”` will assign the value of the expression `x` to the
`foo` property, and re-assign whenever the expression `x` changes.

Events:

Previously only a distinct set of DOM events could be bound using such as `ng-click`, `ng-blur` etc.
`ng-on-*` adds support for binding expressions to any DOM event. For example
`ng-on-bar=”barOccured($event)”` will add a listener to the “bar” event and invoke the
`barOccured($event)` expression.

For properties or events using mixed case underscores can be used before capital letters. For
example `ng-prop-my_prop="x"` will bind `x` to the `myProp` property, and
`ng-on-my_custom_event="x()"` will invoke `x()` on the `myCustomEvent` event.

Fixes angular#16428
Fixes angular#16235
Closes angular#16614
jbedard added a commit to jbedard/angular.js that referenced this issue Jul 30, 2018
…ings

Properties:

Previously only arbitrary DOM attribute bindings were supported via interpolation such as
`my-attribute="{{expression}}"` or `ng-attr-my-attribute="{{expression}}"`, and only a set of
distinct properties could be bound. `ng-prop-*` adds support for binding expressions to any DOM
properties. For example `ng-prop-foo=”x”` will assign the value of the expression `x` to the
`foo` property, and re-assign whenever the expression `x` changes.

Events:

Previously only a distinct set of DOM events could be bound such as `ng-click`, `ng-blur` etc.
`ng-on-*` adds support for binding expressions to any DOM event. For example
`ng-on-bar=”barOccured($event)”` will add a listener to the “bar” event and invoke the
`barOccured($event)` expression.

For properties or events using mixed case, underscores can be used before capital letters. For
example `ng-prop-my_prop="x"` will bind `x` to the `myProp` property, and
`ng-on-my_custom_event="x()"` will invoke `x()` on the `myCustomEvent` event.

Fixes angular#16428
Fixes angular#16235
Closes angular#16614
jbedard added a commit to jbedard/angular.js that referenced this issue Jul 30, 2018
…ings

Properties:

Previously only arbitrary DOM attribute bindings were supported via interpolation such as
`my-attribute="{{expression}}"` or `ng-attr-my-attribute="{{expression}}"`, and only a set of
distinct properties could be bound. `ng-prop-*` adds support for binding expressions to any DOM
properties. For example `ng-prop-foo=”x”` will assign the value of the expression `x` to the
`foo` property, and re-assign whenever the expression `x` changes.

Events:

Previously only a distinct set of DOM events could be bound using directives such as `ng-click`,
`ng-blur` etc. `ng-on-*` adds support for binding expressions to any DOM event. For example
`ng-on-bar=”barOccured($event)”` will add a listener to the “bar” event and invoke the
`barOccured($event)` expression.

For properties or events using mixed case, underscores can be used before capital letters. For
example `ng-prop-my_prop="x"` will bind `x` to the `myProp` property, and
`ng-on-my_custom_event="x()"` will invoke `x()` on the `myCustomEvent` event.

Fixes angular#16428
Fixes angular#16235
Closes angular#16614
jbedard added a commit to jbedard/angular.js that referenced this issue Jul 31, 2018
…ings

Properties:

Previously only arbitrary DOM attribute bindings were supported via interpolation such as
`my-attribute="{{expression}}"` or `ng-attr-my-attribute="{{expression}}"`, and only a set of
distinct properties could be bound. `ng-prop-*` adds support for binding expressions to any DOM
properties. For example `ng-prop-foo="x"` will assign the value of the expression `x` to the
`foo` property, and re-assign whenever the expression `x` changes.

Events:

Previously only a distinct set of DOM events could be bound using directives such as `ng-click`,
`ng-blur` etc. `ng-on-*` adds support for binding expressions to any DOM event. For example
`ng-on-bar="barOccured($event)"` will add a listener to the “bar" event and invoke the
`barOccured($event)` expression.

Since HTML attributes are case-insensitive, property and event names are specified in snake_case
for `ng-prop-*` and `ng-on-*`. For example, to bind property `fooBar` use `ng-prop-foo_bar`, to
listen to event `fooBar` use `ng-on-foo_bar`.

Fixes angular#16428
Fixes angular#16235
Closes angular#16614
jbedard added a commit to jbedard/angular.js that referenced this issue Jul 31, 2018
…ings

Properties:

Previously only arbitrary DOM attribute bindings were supported via interpolation such as
`my-attribute="{{expression}}"` or `ng-attr-my-attribute="{{expression}}"`, and only a set of
distinct properties could be bound. `ng-prop-*` adds support for binding expressions to any DOM
properties. For example `ng-prop-foo="x"` will assign the value of the expression `x` to the
`foo` property, and re-assign whenever the expression `x` changes.

Events:

Previously only a distinct set of DOM events could be bound using directives such as `ng-click`,
`ng-blur` etc. `ng-on-*` adds support for binding expressions to any DOM event. For example
`ng-on-bar="barOccured($event)"` will add a listener to the "bar" event and invoke the
`barOccured($event)` expression.

Since HTML attributes are case-insensitive, property and event names are specified in snake_case
for `ng-prop-*` and `ng-on-*`. For example, to bind property `fooBar` use `ng-prop-foo_bar`, to
listen to event `fooBar` use `ng-on-foo_bar`.

Fixes angular#16428
Fixes angular#16235
Closes angular#16614
@jbedard jbedard closed this as completed in dedb10c Aug 2, 2018
Narretz pushed a commit that referenced this issue Aug 3, 2018
…ings

Properties:

Previously only arbitrary DOM attribute bindings were supported via interpolation such as
`my-attribute="{{expression}}"` or `ng-attr-my-attribute="{{expression}}"`, and only a set of
distinct properties could be bound. `ng-prop-*` adds support for binding expressions to any DOM
properties. For example `ng-prop-foo="x"` will assign the value of the expression `x` to the
`foo` property, and re-assign whenever the expression `x` changes.

Events:

Previously only a distinct set of DOM events could be bound using directives such as `ng-click`,
`ng-blur` etc. `ng-on-*` adds support for binding expressions to any DOM event. For example
`ng-on-bar="barOccured($event)"` will add a listener to the "bar" event and invoke the
`barOccured($event)` expression.

Since HTML attributes are case-insensitive, property and event names are specified in snake_case
for `ng-prop-*` and `ng-on-*`. For example, to bind property `fooBar` use `ng-prop-foo_bar`, to
listen to event `fooBar` use `ng-on-foo_bar`.

Fixes #16428
Fixes #16235
Closes #16614
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants