templateurl - w3schools angularjs service




Invio dell'evento al termine del caricamento di angular.js (8)

Avevo un frammento che veniva caricato in / dopo il partial parziale che veniva tramite il routing.

Avevo bisogno di eseguire una funzione dopo quella subpartial caricata e non volevo scrivere una nuova direttiva e ho capito che si poteva usare un impertinente ngIf

Controller di genitore parziale:

$scope.subIsLoaded = function() { /*do stuff*/; return true; };

HTML di subpartial

<element ng-if="subIsLoaded()"><!-- more html --></element>

Mi sono chiesto quale sia il modo migliore per rilevare la fine del caricamento della pagina / bootstrap, quando tutte le direttive hanno completato la compilazione / il collegamento.

Qualche evento già lì? Dovrei sovraccaricare la funzione bootstrap?


Ho trovato una soluzione relativamente precisa nel valutare quando l'inizializzazione angolare è completa.

La direttiva è:

.directive('initialisation',['$rootScope',function($rootScope) {
            return {
                restrict: 'A',
                link: function($scope) {
                    var to;
                    var listener = $scope.$watch(function() {
                        clearTimeout(to);
                        to = setTimeout(function () {
                            console.log('initialised');
                            listener();
                            $rootScope.$broadcast('initialised');
                        }, 50);
                    });
                }
            };
        }]);

Questo può quindi essere aggiunto come attributo all'elemento body e quindi ascoltato per usare $scope.$on('initialised', fn)

Funziona assumendo che l'applicazione sia inizializzata quando non ci sono più cicli di digest $. $ watch viene chiamato ogni ciclo di digest e quindi viene avviato un timer (setTimeout non $ timeout in modo che non venga attivato un nuovo ciclo di digest). Se un ciclo di digest non si verifica entro il timeout, si presume che l'applicazione sia stata inizializzata.

Ovviamente non è accurato come la soluzione satchmoruns (dato che è possibile che un ciclo digest richieda più tempo del timeout) ma la mia soluzione non ha bisogno che tu tenga traccia dei moduli che lo rende molto più facile da gestire (in particolare per i progetti più grandi ). Ad ogni modo, sembra essere abbastanza preciso per le mie esigenze. Spero che sia d'aiuto.


Queste sono tutte ottime soluzioni, tuttavia, se attualmente stai utilizzando Routing, ho trovato questa soluzione la più semplice e minima quantità di codice necessaria. Utilizzare la proprietà 'resolve' per attendere il completamento di una promessa prima di attivare il percorso. per esempio

$routeProvider
.when("/news", {
    templateUrl: "newsView.html",
    controller: "newsController",
    resolve: {
        message: function(messageService){
            return messageService.getMessage();
    }
}

})

Clicca qui per la documentazione completa - Credito a K. Scott Allen


Se non si utilizza il modulo ngRoute , ovvero non si dispone di $viewContentLoaded .

Puoi usare un altro metodo di direttiva:

    angular.module('someModule')
        .directive('someDirective', someDirective);

    someDirective.$inject = ['$rootScope', '$timeout']; //Inject services

    function someDirective($rootScope, $timeout){
        return {
            restrict: "A",
            priority: Number.MIN_SAFE_INTEGER, //Lowest priority
            link    : function(scope, element, attr){
                $timeout(
                    function(){
                        $rootScope.$emit("Some:event");
                    }
                );
            }
        };
    }

Di conseguenza, la risposta di trusktr ha la priorità più bassa. Oltre $timeout , Angular eseguirà un intero ciclo di eventi prima dell'esecuzione di callback.

$rootScope utilizzato, perché consente di posizionare la direttiva in qualsiasi ambito dell'applicazione e notificare solo i listener necessari.

$ rootScope. $ emit genererà un evento per tutti $ rootScope. $ solo per gli ascoltatori. La parte interessante è che $ rootScope. $ Broadcast notificherà tutti $ rootScope. $ On e $ scope. $ Sugli ascoltatori Source


Se si utilizza Angular UI Router , è possibile ascoltare l'evento $viewContentLoaded .

"$ viewContentLoaded - attivato quando viene caricata la vista, dopo il rendering del DOM ." L'ambito $ della vista emette l'evento. " - Link

$scope.$on('$viewContentLoaded', 
function(event){ ... });

Secondo il team di Angular e questo problema di Github :

ora abbiamo $ viewContentLoaded e $ includeContentLoaded eventi che sono emessi rispettivamente in ng-view e ng-include. Penso che questo sia il più vicino possibile a sapere quando abbiamo finito con la compilation.

Sulla base di ciò, sembra che al momento non sia possibile farlo in modo affidabile, altrimenti Angular avrebbe fornito l'evento fuori dalla scatola.

Il bootstrap dell'applicazione implica l'esecuzione del ciclo di digest nell'ambito della radice e non è inoltre presente un evento terminato nel ciclo di digest.

Secondo i documenti di progettazione di Angular 2:

A causa di più digest, è impossibile determinare e notificare al componente che il modello è stabile. Questo perché la notifica può ulteriormente modificare i dati, che possono riavviare il processo di associazione.

In base a ciò, il fatto che ciò non sia possibile è uno dei motivi per cui è stata presa la decisione di procedere a una riscrittura in Angular 2.


Volevo aggiungere un'altra realizzazione che avevo sulla mia stessa domanda: Angular non ha fornito un modo per segnalare quando una pagina è stata caricata, forse perché "finito" dipende dalla tua applicazione . per esempio, se hai un albero gerarchico di partial, uno carica gli altri. 'finire' significherebbe che tutti sono stati caricati. Qualsiasi framework avrebbe difficoltà a analizzare il codice e a capire che tutto è stato fatto, o ancora atteso. Per questo motivo, è necessario fornire una logica specifica dell'applicazione per controllarla e determinarla.

Grazie

Lior


osservo la manipolazione DOM di angolare con JQuery e ho impostato una finitura per la mia app (una sorta di situazione predefinita e soddisfacente che mi serve per la mia app-abstract) per esempio mi aspetto che il mio ng-repeater produca 7 risultati e lì per i imposterà una funzione di osservazione con l'aiuto di setInterval per questo scopo.

$(document).ready(function(){

  var interval = setInterval(function(){

  if($("article").size() == 7){
     myFunction();
     clearInterval(interval);
  }

  },50);

});




angularjs-scope