Chris
Chris

Reputation: 27394

Angular scoping issues

I have a problem where by a form within my ng-controller doesnt seem to change the properties in the controller that I thought it would. After some reading around it seems I wasn't fully aware of prototypal inheritance, but thanks to the internet and SO I updated my code as such. But unfortunately its still not working and I cannot figure out why.

Here is my HTML

<div ng-app="licenceApp" ng-controller="licenceController">    
    <div class="hover panel" ng-class="{switch : licenceFormVisible}">
        <div class="highlightedSection nosidepad clearfix back">  
            <div class="highlightedSubSection" ng-class="{fullsize : uploadModel.active}" ng-show="!Applying && !FinishedWithErrors && !offlineActivationScreenVisible">
                <h2>Licence File</h2>
                Upload and apply a valid licence file{{uploadModel.active}}<br /><br />
                ...
                <form id="hiddenUploadForm" name="hiddenUploadForm" target="hiddenUploadFormFileTarget" action="/settings/uploadILP" method="post" enctype="multipart/form-data" style="display: none;">
                    <input id="hiddenUploadFormFile" name="file" type="file" ng-model="uploadModel.uploadFileName" onchange="angular.element(this).scope().uploadFileChanged()" />
                    <iframe id="hiddenUploadFormFileTarget" name="hiddenUploadFormFileTarget" iframe-onload="uploadFileFinished()"></iframe>
                </form>
            </div>
        </div>
    </div>

ViewModel

angular.module('licenceApp.controllers', [])
    .controller('licenceController', ['$scope', 'licenceAPIservice', '$filter', '$timeout', function ($scope, licenceAPIservice, $filter, $timeout) {
        $scope.uploadModel = {
            active: false,
            uploadFileName: "",
            uploading: false
        };

        $scope.uploadFileChanged = function () {
            $scope.uploadModel.active = true;
            $scope.uploadModel.uploading = true;

            $('#hiddenUploadForm').submit();
        }
        ...

So when I change uploadModel.active in a function it shows the correct value through a console.log but the display doesnt mimic the new value! Am I still subject to prototypal inheritance here? Note that uploadFileChanged is hit when the input file control is changed.

Upvotes: 0

Views: 66

Answers (1)

Wawy
Wawy

Reputation: 6269

onchange is a javascript event outside angular so you would need to call $apply to notify angular of the changes in the scope. Fortunately there is a angular directive that does that for you (ng-change).

<input id="hiddenUploadFormFile" 
       name="file" type="file" 
       ng-model="uploadModel.uploadFileName"
       ng-change="uploadFileChanged()" />

EDIT:

ngModel doesn't work with input type=file (issue), hence ngChange won't work as it required ngModel to work.

The right way to approach it then would be to call $apply inside you uploadFileChanged function.

HTML:

<input id="hiddenUploadFormFile" 
       name="file" type="file" 
       onchange="angular.element(this).scope().uploadFileChanged()"/>

JS:

    $scope.uploadFileChanged = function () {
        $scope.$apply(function() {
          $scope.uploadModel.active = true;
          $scope.uploadModel.uploading = true;
          $('#hiddenUploadForm').submit();
        });
    }

If you plan to use input type file, it might be work to create a simple directive that handles the change event without the need to access the element scope that way.

Upvotes: 1

Related Questions