AngularJS: Change scope in ngRepeat

0

I have the situation: in the table below, when I click on "edit", it displays the form with the necessary fields (even with a new "cancel" button). So far everything is working well. The problem is that when saving, the form should disappear (ng-hide) and resubmit normal data. Just below is an excerpt from JS. I understand that I can not change the editing after saving.

Table with phones

<form name="telefoneEdit">
    <table class="table table-hover">
        <thead>
            <tr>
                <th width="30%">Telefone</th>
                <th width="20%">Ramal</th>
                <th width="40%">Descrição</th>
                <th width="10%"></th>
            </tr>
        </thead>
        <tbody ng-repeat="telefone in clienteCtrl.cliente.ClienteTelefone" ng-form="tel" ng-init="editing = false">
            <tr ng-show="!editing">
                <td>{{telefone.tel}}</td>
                <td>{{telefone.ramal}}</td>
                <td>{{telefone.descricao}}</td>
                <td class="text-center">
                    <a ng-click="editing = true" class="btn btn-default btn-xs"><i class="icon-pencil2"></i></a>
                </td>
            </tr>
            <tr ng-show="editing">
                <td>
                    <div class="col-md-4">
                        <input ng-model="telefone.ddd" type="number" name="ddd" max="99" ng-maxlength="2" class="form-control input-sm"></input>
                        <label class="error" ng-show="tel.ddd.$invalid">Campo inválido</label>
                        <label class="error" ng-show="erros.ddd">{{erros.ddd[0]}}</label>   
                    </div>
                    <div class="col-md-8">
                        <input type="number" name="telefone" ng-model="telefone.telefone" class="form-control input-sm" ng-minlength="8" required></input>
                        <label class="error" ng-show="tel.telefone.$invalid">Campo inválido</label> 
                    </div>                                  
                </td>
                <td>
                    <input ng-model="telefone.ramal" class="form-control input-sm"></input>
                </td>
                <td>
                    <input ng-model="telefone.descricao" class="form-control input-sm"></input>
                </td>
                <td class="text-center">
                    <button class="btn btn-default btn-xs" type="button" ng-click="editTelefone(telefone)"><i class="icon-disk"></i></button>
                    <a ng-click="editing = false" class="btn btn-default btn-xs"><i class="icon-close"></i></a>
                </td>
                <input type="hidden" ng-model="telefone.id" />
            </tr>
        </tbody>
    </table>
</form> 

Excerpt from JS that should work

$scope.editTelefone = function(telefone) {            
    var erros = {};
    var _data = {};
    _data.ClienteTelefone = telefone;
    self.editing = false;
    $http
        .post('api/cliente_telefones/edit.json',_data)
        .success(function(data){
            if(data.erros) {
                $scope.erros = data.erros;
            } 
            else {
                self.telefone = telefone;
                $scope.erros = false;
                $scope.editing = false;
            }
        })
}

Everything works correctly, I just can not hide the form again.

Illustrative images

Tableinitsoriginal/initialstate

EditingForm

Result after submitting the edit form

    
asked by anonymous 05.01.2016 / 22:15

1 answer

1

One point to note is the use of self . I may be wrong, but from what I know, in the controller we use this or, most commonly used through syntax vm this way:

var vm = this;

But it would be necessary to change the definition syntax of controller in the DOM to controller as vm and all values of scope should have the prefix vm. ex .: ng-show="vm.editing" . As it is not your case, I recommend that you do not use the self reference and directly use $scope .

Another note to make is about setting ng-repeat . You stated directly in the tbody tag, which is not advisable. Since you need to repeat 2 blocks of tr you should use a ng-repeat option that is very rarely used / commented, which would be:

ng-repeat-start="item in items"
&
ng-repeat-end

In your case, it should be used like this:

<tr ng-show="!editing" ng-repeat-start="telefone in clienteCtrl.cliente.ClienteTelefone">
    //.. restante do primeiro bloco de código
</tr>
<tr ng-show="editing" ng-repeat-end>
    //.. restante do bloco de edição
</tr>

As for the problem of hiding the form after editing, the problem happens because the variable $scope.editing is defined inside ng-repeat, that is, for every block that repeats, this variable will always exist, so it will enable / disable all at once.

One solution I used when I had a similar problem was to create a new field inside the array and control the display from that field, leaving its array like this:

$scope.telefones = [
    {id:1, visible: false, telefone: '(48)99665588'},
    //..mais objetos
]

And within controller , we would control the view according to the "visible" field, so only the desired object will be able to edit.

$scope.mostraEdit = function(id) {
  $filter('filter')($scope.telefones, {id: id})[0].visible = true;
};
$scope.escondeEdit = function(id) {
  $filter('filter')($scope.telefones, {id: id})[0].visible = false;
};
$scope.salvaTelefone = function(data) {
  $filter('filter')($scope.telefones, {id: data.id})[0].visible = false;
};

And in the DOM we would have this:

<tr ng-show="!telefone.visible" ng-repeat-start="telefone in telefones" ng-form="tel">
  //.. listagem de telefones
</tr>
<tr ng-show="telefone.visible" ng-repeat-end>
    //.. formulario de edição
</tr>
    
06.01.2016 / 01:45