Egor Popov
Egor Popov

Reputation: 478

angularjs ng-show binding doesn't work with jQuery

I have some ng-repeat

<tr ng-repeat="Picture in Pictures">
    <td>{{Picture.Id}}</td>
    <td>
        <div ng-hide="Picture.editorEnabled">
            {{Picture.Name}}
        </div>
        <div ng-show="Picture.editorEnabled">
            <input ng-model="Picture.editName" class="form-control" ng-show="Picture.editorEnabled">
        </div>
    </td>
    <td>
        <button type="button" name="editButton" class="btn btn-warning" ng-hide="Picture.editorEnabled"
                ng-click="enableEditor(Picture)">Edit
        </button>
        <div ng-show="Picture.editorEnabled">
            <button type="button" name="saveEditButton" class="btn btn-success"
                    ng-click="saveEditor(editName,editImageUrl,Picture)">Save
            </button>
            <button type="button" name="cancelEditButton" class="btn btn-warning" ng-click="disableEditor(Picture)">
                Cancel
            </button>
        </div>
    </td>
</tr>

and here is my controller code:

$scope.enableEditor = function(picture) {
    picture.editorEnabled = true;
    picture.editName      = picture.Name;
    picture.editImageUrl  = picture.ImageUrl;
};

$scope.disableEditor = function(picture) {
    picture.editorEnabled = false;
    picture.editName      = null;
    picture.editImageUrl  = null;
};

$scope.saveEditor = function(name, url, picture) {

    $.ajax({
        url: 'admin/pictures/edit/' + picture.Id,
        type: 'POST',
        data: {
            ImageUrl: url,
            Name: name
        },
        success: function() {
            picture.Name     = picture.editName;
            picture.ImageUrl = picture.editImageUrl;
            $scope.disableEditor(picture);
        }
    });
};

when I click 'Edit' appears editing fields and Save,Cancel buttons. when I click 'Cancel' it dissapears. when I click 'Save' fields saves to DB, method disableEditor executes on same object, I checked Id property, and in debugger it showes that editorEnabled is false, but in my browser still exist Save,Cancel buttons and fields for editing. I click again on 'Save' and it dissapears.

Upvotes: 3

Views: 112

Answers (3)

Anid Monsur
Anid Monsur

Reputation: 4538

You should try using $http instead of $.ajax. jQuery's $.ajax executes outside of Angular's scope. Any code in a callback would not be reflected on your scope because this occurs outside of Angular's digest cycle. Try the following instead:

var url = 'admin/pictures/edit/' + picture.Id;

var data = $httpParamSerializerJQLike({
    ImageUrl: url,
    Name: name
});

var config = {
    headers: {
        'Content-Type': 'application/x-www-form-urlencoded'
    }
};

$http.post(url, data, config).then(function() {
    picture.Name     = picture.editName;
    picture.ImageUrl = picture.editImageUrl;
    $scope.disableEditor(picture);
});

For this to work, you'll need to inject the $http and $httpParamSerializerJQLike services into your controller. I'm assuming you need to submit this as form, since that's how $.ajax works by default. This requires Angular 1.4+.

Note, while it is possible to use $.ajax and then wrap your success code in a $timeout or $scope.$apply(), you're better off using Angular's own $http.

Upvotes: 3

brute_force
brute_force

Reputation: 1171

You need to use $apply every time you use something that is not "angular way", like Anid has already mentioned.

For example if you use jQuery's http instead of angular's $http, you will have to add $scope.$apply.

Upvotes: 0

crackmigg
crackmigg

Reputation: 5901

This does not work because everything that you do in $scope.saveEditor happens outside of angular (I assume $ is jQuery). This is simply not the angular way.

You should have a deeper look into https://docs.angularjs.org/api/ng/service/$http the angular HTTP service, and use that instead.

Upvotes: 2

Related Questions