Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJs: How to re-attach a handler after using ng-if?

I've looked at this question where it says:

When to favor ng-if vs. ng-show/ng-hide?

"For example, if you bound a click handler to one of child elements, when ng-if evaluates to true, that element will be removed from DOM and your click handler will not work any more, even after ng-if later evaluates to true and displays the element. You will need to reattach the handler."

What does it mean to reattach the handler though? For this example here, the function bound to ng-click actually works even when I remove and add the element.

<tr ng-if="!useUserLoginTemplate" class="showRowAnimation">

          <td>Template</td>
          <td>
              <input type="file" file-model="loginTemplateFile">  
              <span class="btn btn-primary" ng-click="uploadLoginTemplateFile()">Upload</span> 
          </td>

</tr>

I cannot access the file using $scope.loginTemplateFile like I do with the versions without ng-if though.

File-model directive linking function:

link: function(scope, element, attrs) {
        var model = $parse(attrs.fileModel);
        var modelSetter = model.assign;

        element.bind('change', function(){
            scope.$apply(function(){
                modelSetter(scope, element[0].files[0]);
            });
        });
 }

What is going on here?

like image 719
user2483724 Avatar asked Apr 08 '14 16:04

user2483724


Video Answer


1 Answers

In theory (not always true, but generally), 'reattaching the handler' applies to handlers that are being generated in imperative code, buried somewhere in a controller or another directive or something. Using a nice declarative directive like ng-click shouldn't be a problem, because those handlers are going to be re-attached for you by Angular whenever that template is rendered. In my subsequent answer to the SO post you cite, I talked about how imperative handlers like that are generally a bad idea, unless they're conditional to some model data that persists between views.

To your more specific question about why you can't access $scope.loginTemplateFile, it would help to have a Fiddle to debug. One question: why not just use ng-model to declare your model binding and keep that cleaner? You can access ng-model information a bit more declaratively then, by using the require: property to inject it, as in this article. (My initial suspicion would be that the form you're using is resulting in the loginTemplateFile property getting written onto multiple scopes somehow, particularly if the template we're seeing is getting rendered into the DOM based on an ng-repeat or something.)

like image 84
XML Avatar answered Sep 27 '22 21:09

XML