AngularJs: how to reattach a handler after using ng-if?

I looked at this question where it says:

When do you prefer ng-if vs. ng-show / ng-hide?

"For example, if you linked a click handler to one of the child elements when ng-if evaluates to true, that element will be removed from the DOM and your click handler will no longer work, even after ng-if later evaluates to true and displays the element You will need to bind the handler again.

What does reconnecting a handler mean? In this example, the function associated with ng-click works even when deleting and adding an item.

<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, as I do with versions without ng-if if.

Link function to the file model directive:

 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's going on here?

+7
angularjs angularjs-directive
source share
2 answers

In theory (not always true, but in general), "re-binding a handler" applies to handlers that are generated in imperative code, somewhere in the controller or another directive, or something else. Using a good declarative directive like ng-click should not be a problem, as these handlers will be reattached to you by Angular whenever this template is displayed. In my subsequent response to the SO post you are quoting, I talked about how these mandatory handlers are generally bad ideas if they are not conditional on some model data that is stored between views.

To your more specific question of why you cannot access $scope.loginTemplateFile , this would help Fiddle debug. One question: why not just use the ng model to declare the model binding and save it? You can access the ng-model information a little more declaratively, then use the require: property to enter it, as in this article . (My initial suspicion was that the form you are using causes the loginTemplateFile property loginTemplateFile become somehow written in multiple clouds, especially if the template we see gets in the DOM based on ng-repeat or something- then.)

+4
source share

You cannot access the file using $scope.loginTemplateFile because the name of your directive is file-model , and you call the name of the directive as an attribute in your link function.

To access the data of the parent area and when you restrict the directive to the Attribute type, refer to the updated code snippet below.

 <input type="file" file-model attrName="loginTemplateFile"> 

Where file-model is your directive, and attrName is the name of the attribute that the link function can reference. I am changing the link function to use the updated attribute name

 link: function(scope, element, attrs) { var model = $parse(attrs.attrName); var modelSetter = model.assign; element.bind('change', function(){ scope.$apply(function(){ modelSetter(scope, element[0].files[0]); }); }); } 

Please refer to angular docs on how to create directives ..

0
source share

All Articles