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

Allow one-time binding for ng-model when ng-model-options getterSetter is true #15643

Open
FstTesla opened this issue Jan 27, 2017 · 3 comments

Comments

@FstTesla
Copy link

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

Feature.

What is the current behavior?

The expression in ng-model directive is evaluated always, even if it is prefixed with ::, which is the correct and reasonable behavior. Anyway, when ng-model-options is present and getterSetter is true, one-time binding could be profitably honored, especially if the model expression evaluates to a getter-setter factory function.

Minimal demo of the problem

Demo. By opening the console, one can see that the ng-model expression is not evaluated once.

What is the expected behavior?

When ng-model-options is present (directly or by inheritance from parent elements) and getterSetter is true, honor one-time binding if specified in the ng-model expression.

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

In the given conditions, the expression returns a function that may or may not change. If it does not change, the overhead of evaluating it every time can be removed. Moreover, if such getter-setter function has some context to be preserved from call to call, one-time binding would remove the need to manually cache it.

@gkalpak
Copy link
Member

gkalpak commented Jan 27, 2017

I am not sure how much work it requires (because the current implementation expects the ng-model expression to be a direct reference to a function). It is probably not worth it imo (considering it won't be a trivial change).

As a work-around, you can achieve a similar behavior by using ngInit to initialize the getterSetterFn:

<input
    ...
    ng-init="getterSetterFn = getterSetterFactory(surname)"
    ng-model="getterSetterFn"
    ng-model-options="{getterSetter: true}" />

Demo

@Thaina
Copy link

Thaina commented Jul 17, 2018

@gkalpak If we have many consecutive init with the same name like that would it not conflict?

<input ng-init="getterSetterFn = getterSetterFactory('name')" ng-model="getterSetterFn" ng-model-options="{getterSetter: true}" />

<input ng-init="getterSetterFn = getterSetterFactory('surname')" ng-model="getterSetterFn" ng-model-options="{getterSetter: true}" />

??

edit: It seem like it conflict and cannot be used. Alternatively we should have some directive to make a scope variable instead of ng-init

@gkalpak
Copy link
Member

gkalpak commented Jul 17, 2018

@Thaina, of course it will conflict if you use the same variable name on the same scope. It is trivial to create your own version of ngInit that also creates a new scope, but the simplest thing to do here is use a unique variable name:

<input
    ng-init="nameGetterSetterFn = getterSetterFactory('name')"
    ng-model="nameGetterSetterFn"
    ng-model-options="{getterSetter: true}" />

<input
    ng-init="surnameGetterSetterFn = getterSetterFactory('surname')"
    ng-model="surnameGetterSetterFn"
    ng-model-options="{getterSetter: true}" />

BTW, this is not related to this issue, because the name conflict would be present regardless if one-time binding is supported for getterSetter in ngModel or not.

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