简体   繁体   中英

angular apply ng-hide on ajax success

I'm trying to display an input field by double-click the name. This works fine! However, how do I switch back if my put-request is successful? I thought I just have to set $scope.edit to false but it does not work. (Made my first steps with angular today)

<ul>
    <li ng-repeat="customer in customers">
        <label>
            <input type="checkbox" ng-model="customer.selected"/>
        </label>
        <span ng-hide="edit" ng-dblclick="edit = true;">{{ customer.name }}</span>
        <label ng-show="edit">
            <input type="text" ng-model="customer.name" ng-keyup="editCustomer($index, customer, $event)"/>
        </label>,
        <small ng-bind="customer.created_at"></small>
        <button ng-click="deleteCustomer($index, customer)">-</button>
    </li>
</ul>

Controller:

$scope.editCustomer = function (index, customer, event) {
    // enter
    if (event.keyCode === 13) {
        $http.put('customers/' + customer.id, customer).success(function () {
            // update customer.name binding
            $scope.edit = false;
        })
    } 
    // esc, do nothing and revert
    else if (event.keyCode === 27) {
        $scope.edit = false;
    }
};

Or is there maybe a better solution for this approach?

This is a common problem. By default ng-repeat creates a child or an isolated scope. So now you are trying to set a variable edit inside the scope of child scope created by ng-repeat but not in the scope of your actual controller.

But inside your controller, you are again trying to set its false value on parent scope not on child scope of `ng-repeat'. To fix this, you need to use an object for this variable.

This behavior is properly explained here: https://github.com/angular/angular.js/wiki/Understanding-Scopes

So modify your HTML code like this:

<ul>
    <li ng-repeat="customer in customers">
        <label>
            <input type="checkbox" ng-model="customer.selected"/>
        </label>
        <span ng-show="!customer.edit" ng-dblclick="customer.edit = true;">{{customer.name}}</span>
        <label ng-show="customer.edit">
            <input type="text" ng-model="customer.name" ng-keyup="editCustomer($event)"/>
        </label>
    </li>
</ul>

And your controller code to:

$scope.editCustomer = function (event) {
    var customer = this.customer;    // current customer can be directly accessed via this
    // enter
    if (event.keyCode === 13) {
        $http.put('customers/' + customer.id, customer).success(function () {
            customer.edit = false;
        })
    } 
    // esc, do nothing and revert
    else if (event.keyCode === 27) {
        customer.edit = false;
    }
};

Hope this helps!

Thanks,
SA

You must use both ng-hide and ng-show if you want to show and hide your input. It's not logical but is the only way that it works in my controller, could be a bug.

<label ng-show="edit" ng-hide="edit-hide">
  <input type="text" ng-model="customer.name" ng-keyup="editCustomer($index, customer, $event)"/>
</label>


// Show control
$scope.edit = true;
$socpe.edit_hide = false;

// Hide control
$scope.edit = false;
$scope.edit_hide = true;
<ul>
    <li ng-repeat="customer in customers">
        <label>
            <input type="checkbox" ng-model="customer.selected"/>
        </label>
        <span ng-show="!edit" ng-dblclick="edit = true;">{{ customer.name }}</span>
        <label ng-show="edit">
            <input type="text" ng-model="customer.name" ng-keyup="editCustomer($index, customer, $event)"/>
        </label>,
        <small ng-bind="customer.created_at"></small>
        <button ng-click="deleteCustomer($index, customer)">-</button>
    </li>
</ul>

Controller:

$scope.editCustomer = function (index, customer, event) {
    // enter
    if (event.keyCode === 13) {
        $http.put('customers/' + customer.id, customer).success(function () {
            // update customer.name binding
            $scope.edit = false;
        })
    } 
    // esc, do nothing and revert
    else if (event.keyCode === 27) {
        // $scope.edit = false;
    }
};

Remember set default value $scope.edit = false on start of your controller.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM