AngularJS directive does not immediately read ng-show / ng-hide

I have the following HTML section in a corner application. The <div /> tag for the destination list shows the list of destinations. This directive is basically a table.

<div ng-show="loading">Loading...</div> <div ng-show="!loading && (appointments.length == 0)">No Appointments Found</div> <div ng-hide="loading || (appointments.length == 0)">Test123</div> <div ng-hide="loading || (appointments.length == 0)" appointment-list source="appointments" appointment-selected="appointmentSelected(appointment)"></div> 

Then I have the following in the controller. I set the load variable while something is in flight, and then I also filter the appointments on the page according to the text in the text box.

  $scope.$watch('selectedDate', function(newVal, oldVal) { if (newVal) { $scope.loading = true; Appointment.query({year: newVal.getYear()+1900, month: newVal.getMonth()+1, day: newVal.getDate()}, function(data) { $scope.allAppointments = data; $scope.appointments = $scope.filterAppointments(); $scope.loading = false; }); } }); 

My problem is that hiding the div for my custom directive is going wrong. The table should disappear exactly along with the line "Test123", but it doesn’t. When I move from the selected date with a table filled to a date where there is nothing, β€œTest123” will be replaced by the download (for this it will be hidden and the download will be shown), but the table remains until the download process is complete, after why the table will disappear

Can someone explain why the delay? Why doesn't the directive respond exactly like the div above it?

Edit

Here is plnkr which shows the problem: http://plnkr.co/edit/khxQuaM6sxTx5RszvowX?p=preview

Basically click on the buttons at the top to load two datasets. I have a timeout to simulate some time on the server. Whenever you see "Loading ...", the div for the meetingList table should not be displayed, since ng-hide will evaluate to true because the load is true, but does not disappear.

+4
source share
4 answers

You need to use $parent to access the loading model, as the appointmentList directive creates an isolated area. Make the following changes to the last div containing the table, and you will achieve the desired effect.

 <div ng-hide="$parent.loading || (appointments.length == 0)" appointment-list source="appointments" ... ></div> 

You do not need to use $parent to refer to appointments , since you are passing this model into a directive. But there is no harm to add $parent as $parent.appointments.length == 0 , since you are still defined in the parent area.

Btw, you should also set appointments as empty in an observer like this

 if (newVal) { $scope.loading = true; $scope.appointments = []; //add this 

to make the appointments.length == 0 condition useful.

+5
source

Is $scope.appointments within the same tick as $scope.loading ?

If $scope.filterAppointments does something asynchronous, you should make sure $scope.loading set to false at the end of this process.

0
source

In my case, angular did not want to show / hide when applied to the element ul> li, in IE or Chrome. Changing it to a div works fine. I am on angular 1.2.14. Not sure if this is a mistake or not, but it seems to be.

0
source

I had the same problem. I used ng-cloak, it does not allow the browser to display the template while loading my application.

Take a look at this: http://weblog.west-wind.com/posts/2014/Jun/02/AngularJs-ngcloak-Problems-on-large-Pages

0
source

Source: https://habr.com/ru/post/1497714/


All Articles