6

For some reason binding doesn't work on an input within ng-if block in a directive

so this, doesn't work:

app.directive 'foo', ->
    restrict: 'E'
    scope:
       type:'='
    template: "<input ng-if=\"type === 'string'\" ng-model='filterText'>
                  <div> {{filterText}} </div>"


<foo type="'string'" />

it works fine outside of directive or without ng-if. Wrapping input inside of a div with ng-if not helping. Is it a bug?

jsbin link

iLemming
  • 34,477
  • 60
  • 195
  • 309
  • What isn't working? Your jsbin link seems fine to me. If I change type to 'test' the input hides. Isn't that what you're looking for? – sma Sep 29 '14 at 19:55
  • no, you see it's not displaying {{filterText}} as it should. And if you remove ng-if it works fine – iLemming Sep 29 '14 at 19:56
  • possible duplicate of [Angularjs ng-model doesn't work inside ng-if](http://stackoverflow.com/questions/18342917/angularjs-ng-model-doesnt-work-inside-ng-if) – zs2020 Sep 30 '14 at 00:00

3 Answers3

5

It is caused by the ng-if introducing a new scope combined with the fact that you ng-model "has not dot in it".

This works:

template: "<div ng-init='holder={}'> <input ng-if=\"type === 'string'\" ng-model='holder.filterText'></div>
               <div> {{holder.filterText}}</div>"

See the directive info at https://docs.angularjs.org/api/ng/directive/ngIf and notice the text "This directive creates new scope." For the "dot-in-model", see for example Does my ng-model really need to have a dot to avoid child $scope problems? or https://egghead.io/lessons/angularjs-the-dot Basically when reading the value it will be read correctly traversing scope prototypes, but when modifying the value it will be written to the very own scope.

Community
  • 1
  • 1
eekboom
  • 5,551
  • 1
  • 30
  • 39
  • I have a link to jsbin, feel free to play with that. Apparently it's not scoping problem, this seems to be something different – iLemming Sep 29 '14 at 19:53
  • Sorry, did not notice the small blue link. I don't understand why you say "Apparently it's not scoping problem". See my edited answer where I illustrated my point with code. – eekboom Sep 29 '14 at 20:02
  • Oh... interesting... this http://jsbin.com/penuhilahujo/9/edit worked. So you're right – iLemming Sep 29 '14 at 20:06
1

Since ng-if creates a new scope, you just need to do this

ng-model='$parent.filterText'

Also, please check this answer.

Community
  • 1
  • 1
zs2020
  • 53,766
  • 29
  • 154
  • 219
-3

The <div> tag isn't closed in your example, nor is the ng-if applied to that node.

Try this:

template: "<input  ng-model='filterText'>
                  <div ng-if=\"type === 'string'\"> {{filterText}}"</div>"
sma
  • 9,449
  • 8
  • 51
  • 80