ottercoder ottercoder - 4 months ago 17
Javascript Question

Using $watch, table div dissapear

I'm using

isteven-multi-select
directive for multi-select dropdown. I'm giving it
thingsList
and it creates
checkedList
while I choose things.

So at first I used button to confirm selection and
ng-click
triggered
postFunction
with
checkedList
. And it worked fine.

But then I decided to add a watcher so I wouldn't need to press the button. As I can see at debug mode it's working (list is updates correctly), but there is a problem. I'm showing updated list at the page with
datatables
. But somehow, after choosing anything at dropdown ($watch event)
<div> with table
is dissapearing. And it'not ng-show or something it dissapears from DOM itself.

I have no idea why.

this.postThings = function (checkedList) {
$http.post("/list/" JSON.stringify(checkedList)).then(
function success(response) {
$scope.thingsList.splice(0);
Array.prototype.push.apply($scope.thingsList, response.data);
},
function error(data) {
console.log(data);
$.notify({message: data.data.message}, {type: 'danger'});
}
);
};


$scope.$watch(function (scope) {
return scope.checkedList
},
function (newValue, oldValue) {
if ($scope.checkedList.length == 0) {
vm.bindBack();
} else {
vm.bindNew($scope.checkedList);
}
});


directive:

<isteven-multi-select input-model="thingsList"
output-model="checkedList"
button button-label="icon name"
item-label="icon name maker"
tick-property="check">
</isteven-multi-select>


HTML that dissapears:

...
<div class="table-responsive">
<h3>Things:/h3>
<table datatable="ng" class="display">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="thing in thingsList">
<td>{{thing .id}}</td>
<td><a ui-sref="thing Info({thing Id: thing .id})">{{thing .name}}</a></td>
</tr>
</tbody>
</table>
</div>
...

Answer

Found the problem. There's known bug in angular-datatables, where multiple rerenderings somehow erase < table > from the DOM. https://github.com/l-lin/angular-datatables/issues/729

So the idea is to stop constant rerendering, not trigger the bug.

For me solution was, to add checking if newValue has different length then oldValue. Now there's no constant rerender and it works fine.

$scope.$watch(function (scope) {
        return scope.checkedList
    },
    function (newValue, oldValue) {
     if(newValue.length != oldValue.length) {
        if ($scope.checkedList.length == 0) {
            vm.bindBack();
        } else {
            vm.bindNew($scope.checkedList);
        }
     }
    });