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

feature($compile): a switch to disable the old (pre-ES6) way to init bindings #14362

Closed
thorn0 opened this issue Apr 2, 2016 · 6 comments
Closed

Comments

@thorn0
Copy link
Contributor

thorn0 commented Apr 2, 2016

Do you want to request a feature or report a bug?

feature

What is the current behavior?

From the docs for $compile:

Deprecation warning: although bindings for non-ES6 class controllers are currently bound to this before the controller constructor is called, this use is now deprecated. Please place initialization code that relies upon bindings inside a $onInit method on the controller, instead.

There is no possibility currently to disable this deprecated behavior.

What is the expected behavior?

$compileProvider.enableDeprecatedEarlyBinding(false) should turn off this behavior.

Or even better, if we could disable it on per-directive basis.

What is the motivation / use case for changing the behavior?

Because of this deprecated behavior, it's impossible to use simple property initializers in TypeScript to specify default values for properties that have optional bindings associated with them.

class Foo {
  binding = 2;
}

It looks nice and simple, but if the bound attribute exists, the default value overwrites the initial value of the binding. So for now, the initializers have to look unappealing like this:

class Foo {
  binding: number = this.binding || 2;
}

Also this won't really work for situations like boolean properties, empty strings as initial values of bindings, etc. And note that we had to specify the type as it can't be inferred from the self-referring initializer expression.

@Narretz
Copy link
Contributor

Narretz commented Apr 4, 2016

This does sound like a reasonable request, although a global config will have adverse effects on some ES5 style directives that expect the bindings to be bound at construct time. Granted, many won't be using that style, but it's a valid concern. Putting a switch into the DDO could be a possibility. Maybe you want to create a POC PR?

@petebacondarwin
Copy link
Contributor

I think that the best way to achieve this, without the facility requested in this issue would be:

class Foo {
  binding: number;
  $onInit() {
    this.binding = this.binding || 2;
  }
}

@petebacondarwin
Copy link
Contributor

It would not be too difficult to do this on a per component/directive basis, since we could use a flag in the DDO/CDO to change the initialization behaviour.

@thorn0
Copy link
Contributor Author

thorn0 commented Apr 4, 2016

What can be the name for the flag? Why not make the new behaviour default for components? Also this syntax - this.binding || 2 - has a problem with falsy values. It'd be much simpler if the initial value of the binding was assigned to the property after the default value.

@petebacondarwin
Copy link
Contributor

@thorn0 I agree that falsy values are not dealt with by this example (it was based on your original case :-) ). We could have the default behaviour be what you suggest but only in 1.6, since we cannot break the current behaviour in 1.5.

For the flag, how about prepopulateBindings or something?

In 1.6 we should just get rid of all of this pre-populating machinery and not even provide a flag.
That would require everyone to move their initialization code that depends upon bindings from their controllers into the $onInit function. But I think that is reasonable.

@thorn0
Copy link
Contributor Author

thorn0 commented Sep 14, 2016

Implemented in #15095

@thorn0 thorn0 closed this as completed Sep 14, 2016
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