admin管理员组

文章数量:1389754

I currently have a few ng-repeats in my view for building an agenda. Whenever I have a ng-repeat I can include a directive checking if the ng-repeat is done to trigger a method. Works perfect...

The problem is, I have like 5 ng-repeats, I don't want to include the directive for all 5 ng-repeats and check in the method if all 5 have called the method... I just want a way to detect if all my ng-repeats (and other angular stuff) is finished building the view so for example I can put appointments in the agenda via JQuery. Because ofcourse, putting appointments in the agenda (divs) before the agenda (divs) have been created won't work.

Thanks in advance!

UPDATE:

I'm using a REST backend to get the appointments from. So i can't just retrieve the appointments and try to show them in the agenda because the view might not be finished generating (using the ng-repeats)....

So I need something that is triggerd ones the view is done generating (ALL ng-repeats must be done) so i can start placing the appointments.

I currently have a few ng-repeats in my view for building an agenda. Whenever I have a ng-repeat I can include a directive checking if the ng-repeat is done to trigger a method. Works perfect...

The problem is, I have like 5 ng-repeats, I don't want to include the directive for all 5 ng-repeats and check in the method if all 5 have called the method... I just want a way to detect if all my ng-repeats (and other angular stuff) is finished building the view so for example I can put appointments in the agenda via JQuery. Because ofcourse, putting appointments in the agenda (divs) before the agenda (divs) have been created won't work.

Thanks in advance!

UPDATE:

I'm using a REST backend to get the appointments from. So i can't just retrieve the appointments and try to show them in the agenda because the view might not be finished generating (using the ng-repeats)....

So I need something that is triggerd ones the view is done generating (ALL ng-repeats must be done) so i can start placing the appointments.

Share Improve this question edited May 12, 2015 at 15:40 Bas Van Den Heuvel asked May 12, 2015 at 14:50 Bas Van Den HeuvelBas Van Den Heuvel 1371 silver badge10 bronze badges 8
  • Do you have any demo to see the issue ? – Shidhin Cr Commented May 12, 2015 at 14:56
  • 1 If your appointments are in the form of data (which they should be, leave the formatting to the view) I doubt you're gonna have a problem. What you're describing is more of a JQuery-esque problem where you inject HTML into your DOM. Your ng-repeats know which data they're looking for, and they'll be sure to grab it when they're rendered. – UncleDave Commented May 12, 2015 at 14:56
  • I indeed use JQuery to put the appointments (divs) in the correct divs in the agenda. For example the monday 08:00 div will have the unique ID 1-0800. After the agenda has been created i use JQuery to find this div and place the appointment div in that div... – Bas Van Den Heuvel Commented May 12, 2015 at 14:59
  • Although angular could happily do that for you - I believe if your JQuery script tag is below your Angular script tag and at the bottom of the body you should be fine. Perhaps also wrap your jquery code in a $(document).ready(function () { }); Also if you'd care to post your code we could perhaps suggest a better way to do some things. – UncleDave Commented May 12, 2015 at 15:02
  • 1 I would suggest not to do id's manipulation in angular... it can very easily handle such scenarios without going to jquery... – harishr Commented May 12, 2015 at 15:43
 |  Show 3 more ments

4 Answers 4

Reset to default 1

You should use $viewContentLoaded rather than any directive as this fires after everything in the view loaded. Documentation : https://docs.angularjs/api/ngRoute/directive/ngView

Code Example : $scope.$on('$viewContentLoaded', function(event) { // Your Code Goes Here }); Note that this will only work if you are using ng-view from routing.

there´s a trick in Angular using a $timeout to delay execution of certain parts of the code until all directives have redered. I'm not sure it will work in this instance but you could try.

In your controller simply add

$timeout(function() {
  // code to execute after directives goes here
});

You're probably better off not using jQuery to populate the agenda, but using Angular instead. This allows you to just wait until the data is loaded, which is much easier to detect, and Angular will make sure the DOM gets uploaded whenever it can do so.

In your case you can probably do something like this:

Controller:

$scope.days = [];
//Here we create the days for the calendar (7 in this case)
for (var i = 0; i < 7; i++) {
    var hours = [];
    //and the hours, with an empty appointment array for each hour
    for (var i = 0; i < 24; i++) {
        hours.push({ appointments: [] });
    }
    $scope.days.push({
        hours : hours
    }); 
}
//Then we can get the appointments from your api
getAppointments().then(function(appointments) {
    //and add the results to the arrays created above
    appointments.forEach(function(appointment) {
        //This is some simplified logic that only uses the day of the week
        //and hour of the appointment. Your logic would probably a bit more plex 
        //to properly put the appointment in the correct array
        var day = appointment.date.getDay();
        var hour = appointment.date.getHour();
        $scope.days[day].hours[hour].appointments.push(appointment);
    });
});

Template:

<div class="days" ng-repeat="day in days">
    <div class="hours" ng-repeat="hour in day.hours">
        <!-- I assume you have one hours div in which all appointments for that hour will go -->
        <div class="appointments" ng-repeat="appointment in hour">
            {{ appointment.title }}
        </div>

    </div>
</div>

That said, if you really want to detect when the view has finished loading then you have a couple of options:

  1. Wait for all your data being loaded and then use a $timeout to ensure it has been rendered.

It would look something like this:

var somePromise = getPromise();
var someOtherPromise = getOtherPromise();
$q.all([somePromise, someOtherPromise])
    .then(function() {
        //At this point all data is available for angular to render
        $timeout(function() {
            //and now everything should actually be rendered
        });
  1. Listen for the $viewContentLoaded, but this only works if you use ng-view and might fire too early if your data is loaded asynchronous (I'm not entirely sure about the details here, since I usually avoid detecting when the view is loaded).

  2. If all of the above fails you could just continuously check if the desired elements are loaded on the page.

You can use angularjs's directive to make it. With directive you can set the ready event for any dom element.

For more detail, refer to this great post and question.

本文标签: javascriptAngular detect if view is finishedStack Overflow