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

feat(ngModelController): expose $setModelValue #5221

Closed
wants to merge 1 commit into from

Conversation

g00fy-
Copy link

@g00fy- g00fy- commented Dec 1, 2013

General usecase:

  • allow other directives requiring ngModel to easily assign model value
  • $setViewValue works only with basic "flat" values like strings or numbers (eg not objects).

currently similar thing can be achieved by using

$parse(attr.ngModel).assign(scope.$parent,modelValue)

but this approach gets more complicated with multiple directives and isolate scopes.

Specific usecase:

AutoComplete input directive returning objects instead of values.

<input type="text" auto-complete-user ng-model="user">

parser:

function(value){ return {name:value} )

formatter:

function(value){
  return angular.isObject(value) ? value.name : value 
}

the user list dropdown template:

<li ng-repeat="user in users" ng-click="select(user)">{{user.name}}</li>

and the select function would be:

function(user){
  ngModel.$setModelValue(user)
}

general usecase:
- allow other directives requiring `ngModel` to easily assign model value
- `$setViewValue` works only with basic "flat" values like strings or numbers (eg not objects).

currently similar thing can be achieved by using 

`$parse(attr.ngModel).assign(scope.$parent,modelValue)`


Specific usecase:

AutoComplete input directive returning objects instead of values.

`<input type="text" auto-complete-user ng-model="user">`

parser:
`function(value){ return {name:value} )`

formatter:
`function(value){ return angular.isObject(value) ? value.name : value }`

the user list dropdown template:

`<li ng-repeat="user in users" ng-click="select(user)">{{user.name}}</li>`

and the `select` function would be:
`function(user){ngModel.$setModelValue(user)}`
@mary-poppins
Copy link

Thanks for the PR!

  • Contributor signed CLA now or in the past
    • If you just signed, leave a comment here with your real name
  • PR's commit messages follow the commit message format

If you need to make changes to your pull request, you can update the commit with git commit --amend.
Then, update the pull request with git push -f.

Thanks again for your help!

@MikeMcElroy
Copy link
Contributor

I don't really understand the use case... could you elaborate more on it or
show a plunkr of it?

I would think that the parsers and formatters would handle all the
transformation from objects to flat values that you might want.

On Sun, Dec 1, 2013 at 9:18 AM, Mary Poppins [email protected]:

Thanks for the PR!

  • Contributor signed CLAhttps://github.com/angular/angular.js/blob/master/CONTRIBUTING.md#signing-the-clanow or in the past
  • If you just signed, leave a comment here with your real name
    • PR's commit messages follow the commit message formathttps://github.com/angular/angular.js/blob/master/CONTRIBUTING.md#git-commit-guidelines

If you need to make changes to your pull request, you can update the
commit with git commit --amend.
Then, update the pull request with git push -f.

Thanks again for your help!


Reply to this email directly or view it on GitHubhttps://github.com//pull/5221#issuecomment-29575491
.

@g00fy-
Copy link
Author

g00fy- commented Dec 1, 2013

@MikeMcElroy: I need it the other way round -> get an object (like a User instance) from ngModel not a String or a Number.
see punkr:
http://plnkr.co/edit/KdFyXo7SSeHGIXos5mSl?p=preview

@petebacondarwin
Copy link
Contributor

I think you should still be using setViewValue. The problem you have is that your $parser only understands strings, unlike the formatter that can handle either.
What about this instead: http://plnkr.co/edit/U2wNyvykkQOISqRLSE6f?p=preview

By the way, it is rather dangerous to add in sibling elements like this without the proper memory management. It is best to create a new scope for the extra elements and make sure you tidy them up when the input is destroyed.

@petebacondarwin
Copy link
Contributor

Subverting the $parser pipeline by writing directly to the model prevents the directive from interoperating well with other directives, such as validators.

@g00fy-
Copy link
Author

g00fy- commented Dec 3, 2013

@petebacondarwin
While I believe that solution like $setModelValue may be flawed, there is still no way to set the $modelValue so that the $viewValue gets updated and cause the input value to render properly.

The punkr example you have provided doesn't update the input field ($liewValue) and it seems there is no easy way of doing that with formatters.

Running $render() in formatter may cause an infinite loop

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants