2

I'm developing an AngularJS application, using v1.3.9. I have a couple ng-if directives which are always evaluating true, and I can't figure out why.

<tr data-ng-repeat="line in chat">
                    <td class="message-timestamp">{{line.time | date:'short'}}</td>
                    <div ng-if="line.type === 'gist'">
                        <td class="message-nick">{{line.nick}}</td>
                        <td class="message-text">{{line.message}}
                            <p>
                                <code ng-show="showGist" walrus-auto-gistify data-gist-id="{{line.options[0]}}"></code>
                                <br>
                                <button ng-click="showGist = !showGist" class="btn btn-primary btn-xs">Show/Hide</button>
                            </p>
                        </td>
                    </div>
                    <div ng-if="false">
                        <td class="message-nick"><span class="glyphicon glyphicon-arrow-right"></span></td>
                        <td class="message-text">{{line.message}}</td>
                    </div>
                </tr>

When I run this, both ng-if directives are evaluated as true, so both divs are displayed.

chat is just an array of objects.

jaredready
  • 2,398
  • 4
  • 23
  • 50
  • Are you sure your code is reloading in the browser? That ng-if="false" should never show anything....maybe inspect the code in the browser to make sure what's there is what you think you have. – Arthur Frankel Apr 07 '15 at 20:04
  • Your first question might be relevant. These `ng-if` elements are created after page load. – jaredready Apr 07 '15 at 20:05
  • @KevinB they're created as stuff gets pushed onto `chat`. There's a service which holds the data, as elements are pushed onto it a call to `$rootScope.apply()` is made – jaredready Apr 07 '15 at 20:09
  • So the html (or, elements) isn't created, the data that drives it is. that's different and shouldn't affect the `ng-if` working. – Kevin B Apr 07 '15 at 20:24
  • Well, if I begin with `data.length == 0` and then `data.length == 1`, then all those elements are created, right? – jaredready Apr 07 '15 at 20:25
  • By angular, yes, but your code isn't "creating" the html, your code just updates the data. If you were creating the html and appending it in some weird way, it would be possible for the html to not be parsed by angular at all, thus making the ng-if not do anything. – Kevin B Apr 07 '15 at 20:33
  • Yes, agreed (with @Kevin B)...probably need to $compile it. – Arthur Frankel Apr 07 '15 at 20:35
  • Angular is creating the dom elements, which is desired. The fact is, the `ng-if`s are being ignored – jaredready Apr 07 '15 at 20:35

1 Answers1

5

I'm pretty sure it has to do with the fact that you have a <div> as a direct child of a <tr>. I've had issues with this type of design in the past where it causes strange behavior.

A solution to this is to put the <div>'s within the <td>, like below:

<tr data-ng-repeat="line in chat">
    <td class="message-timestamp">{{line.time | date:'short'}}</td>
    <td class="message-nick">
        <div ng-if="line.type === 'gist'">{{line.nick}}</div>
        <div ng-if="line.type !== 'gist'"><span class="glyphicon glyphicon-arrow-right"></span></div>
    </td>
    <td class="message-text">
        <div ng-if="line.type === 'gist'">
            <p>
                <code ng-show="showGist" walrus-auto-gistify data-gist-id="{{line.options[0]}}"></code>
                <br />
                <button ng-click="showGist = !showGist" class="btn btn-primary btn-xs">Show/Hide</button>
            </p>
        </div>
        <div ng-if="line.type !== 'gist'">{line.message}}</div>
    </td>
</tr>

EDIT: Attempt at a JSFiddle here

brettvd
  • 486
  • 2
  • 5
  • You got it. I didn't even think about checking to make sure that `
    `s were valid children of ``s. Thank you so much for pointing this out!
    – jaredready Apr 08 '15 at 00:47