2016-08-08 8 views
0

Ich habe immer noch Probleme mit meiner Datenbank, aber ich fand heraus, dass die Probleme von der Tatsache herrühren, dass das Öffnen der Datenbank einige Zeit in Anspruch nimmt, die App aber nicht Warten bis diese Aufgabe beendet ist.AngularJS + wie man wartet, bis die Aufgabe beendet ist, bevor die nächste Aufgabe ausgeführt wird

Gibt es eine Möglichkeit, eckig zu warten, bis die Datenbank korrekt geöffnet wird, bevor die nächste Aufgabe gestartet wird?

Danke, Christian.


Update: 2016.08.08 - 03.13

Danke für alle Antworten. Wie ich sehen kann, war meine erste Idee mit Versprechen ($ q) richtig, aber:

Meine App hat eine app.js, die meine Hauptdatei ist. Es ruft nur die InitDB auf. Dies sollte die Datenbank öffnen. Dann sollte es die CreateTables aufrufen, das erstellt die Tabelle, wenn sie nicht existiert.

Der Rest meiner App ist in 4 Seiten (Vorlagen) aufgeteilt. Jede Seite hat ihren eigenen Controller.

Also die Idee war, die db zu initalisieren, um die Tabelle zu erstellen, und dann mit der Datenbank arbeiten, aber über verschiedene Controller verwendet.

Das wird nicht funktionieren, weil ich immer alle meine Sachen in die .then() meiner initDB in der app.js ???

Dies ist meine erste AngularJS app, vielleicht ist das der Grund, warum ich eine Menge Fehler machen ...

Danke, Christian.

+1

Sie mit dem Versprechen funktionieren könnte, und es zu lösen, wenn Datenbank ist: https://docs.angularjs.org/api/ng/service/$q –

Antwort

0

Eines der Kernkonzepte von Angular ist die Arbeit mit Services/Factories. Es gibt umfangreiche Dokumentationen und Blogs darüber, wie diese funktionieren und wie sie verwendet werden, aber die Grundidee ist, dass es sich um Singleton-Controller handelt, die gemeinsam genutzte Daten und Methoden in Ihrer gesamten Anwendung handhaben. In Kombination mit Versprechen können Sie problemlos einen Dienst erstellen, der die Kommunikation mit Ihrer Datenbank verwaltet.

angular 
    .module('myApp') 
    .service('DBService', DBService) 
    .controller('Ctrl1', Ctrl1) 
    .controller('Ctrl2', Ctrl2) 
    .controller('Ctrl3', Ctrl3) 
    .controller('Ctrl4', Ctrl4); 

DBService.$inject = ['$q']; 
function DBService($q) { 
    var DBService = this; 
    var DBServiceDeferred = $q.defer(); 
    DBService.ready = DBServiceDeferred.promise; 

    // a service is only initialized once, so this will only ever be run once 
    (function() { 
    init(); 
    })(); 

    function init() { 
    // you can use promise chaining to control order of events 
    // the chain will halt if any function is rejected 
    initDB() 
    .then(createTablesUnlessExist) 
    .then(setDbReady); 
    } 

    function initDB() { 
    var deferred = $q.defer(); 
    // simulate async db initialization 
    $timeout(function() { 
     deferred.resolve(); 
     // or reject if there is an error 
     // deferred.reject(); 
    }, 5000); 
    return deferred.promise; 
    }; 

    function createTablesUnlessExist() { 
    //create tables if needed (only happens once) 
    var deferred = $q.defer(); 
    // simulate async table creation 
    $timeout(function() { 
     deferred.resolve(); 
     // or reject if there is an error 
     // deferred.reject(); 
    }, 5000); 
    return deferred.promise; 
    } 

    function setDbReady() { 
    DBServiceDeferred.resolve(); 
    } 
} 

Jetzt haben Sie Ihr DB-Setup und Sie müssen sich nicht mehr darum kümmern. Sie können von jedem Controller, der den Service verwendet, auf die Datenbank zugreifen. Keine der Abfragen wird ausgeführt, bis die Datenbank initialisiert und die Tabellen erstellt wurden.

Ctrl1.$inject = ['DBService', '$q']; 
function Ctrl1(DBService, $q) { 
    $q.when(DBService.ready).then(function() { 
    DBService.conn.query("Select something"); 
    }); 
} 
Ctrl2.$inject = ['DBService', '$q']; 
function Ctrl2(DBService, $q) { 
    $q.when(DBService.ready).then(function() { 
    DBService.conn.query("Select something"); 
    }); 
} 
Ctrl3.$inject = ['DBService', '$q']; 
function Ctrl3(DBService, $q) { 
    $q.when(DBService.ready).then(function() { 
    DBService.conn.query("Select something"); 
    }); 
} 
Ctrl4.$inject = ['DBService', '$q']; 
function Ctrl4(DBService, $q) { 
    $q.when(DBService.ready).then(function() { 
    DBService.conn.query("Select something"); 
    }); 
} 
+0

Hallo JoelCDoyle, dies ist eine der intrestings Antworten Ich lese. Vielen Dank! Aber jetzt habe ich noch andere Fragen: 1. In Ihrer Fabrik rufen Sie direkt die Funktion init() auf. Ist das sicher? Das würde bedeuten, dass sich die Sache beim Starten der App inizialisiert? Wie schließt man es, wenn die App geschlossen ist? 2. Ich dachte, ich müsste die gesamte Datenbanklogik (CRUD) in die Fabrik stellen, aber Sie rufen sie von den Controllern an? Ist dies nur für das schnelle Beispiel, oder ist das Best Practices? 3. Wenn in der Steuerung der DBService nicht bereit ist, werden die Tasks warten oder einen Fehler erzeugen? Endlosschleife? – cjs1976

+0

Hallo nochmal. Ich habe meine Factory komplett mit all Ihren Hinweisen neu geschrieben, aber ich bekomme immer einen Fehler, wenn es um die Funktion setDbReady() geht. Anstelle von DBService habe ich PersistenceService genommen. Also wenn ich die PersistenceService.ready.resolve(); Ich erhalte den Fehler TypeError: PersistenceService.ready.resolve ist keine Funktion ... Irgendeine Idee? Danke, Christian. – cjs1976

+0

Sie haben Recht, Sie wollen nicht wirklich Abfragen innerhalb der Controller machen, das war nur zu Demonstrationszwecken. Sie möchten in Ihrem Service Methoden erstellen, die die Controller aufrufen können, um Abfragen durchzuführen. In meinem Code ist ein Fehler aufgetreten. Hier ist ein Plünderer mit dem korrigierten, funktionierenden Code. Beobachten Sie die Konsole, um die Reihenfolge der Vorgänge zu sehen: https://plnkr.co/edit/AWtM0lF2491fFutqQYaz?p=preview –

0

Angular bietet einen Service $ q. Ein Dienst, mit dem Sie Funktionen asynchron ausführen und deren Rückgabewerte (oder Ausnahmen) nach der Verarbeitung verwenden können. Siehe hierzu die Dokumentation https://docs.angularjs.org/api/ng/service/$q. $ q dreht sich im Grunde um die Konzepte der Versprechen. Versprechen in AngularJS werden von dem integrierten $ q-Dienst bereitgestellt.

0

Schreiben Sie eine Methode, die überprüft, ob die Verbindung hergestellt ist oder nicht ... die wahr oder falsch zurückgibt.

app.controller('MainCtrl', function($scope, httpq) { 
    http.get('server call method') 
     .then(function(data) { 
     if(data.conn==true) 
     // do what u want 
     //write other calls 
     }) 
     .catch(function(data, status) { 
     console.error('error', response.status, response.data); 
     }) 

    }); 
0

können Sie $ q-Bibliothek verwenden

Beispiel:

app.service("githubService", function ($http, $q) { 
var deferred = $q.defer(); 

this.getAccount = function() { 
    return $http.get('https://api.github.com/users/haroldrv') 
     .then(function (response) { 
      // promise is fulfilled 
      deferred.resolve(response.data); 
      // promise is returned 
      return deferred.promise; 
     }, function (response) { 
      // the following line rejects the promise 
      deferred.reject(response); 
      // promise is returned 
      return deferred.promise; 
     }) 
    ; 
}; 

});

unter Verwendung der oben Service:

app.controller("promiseController", function ($scope, $q, githubService) { 
githubService.getAccount() 
    .then(
     function (result) { 
      // promise was fullfilled (regardless of outcome) 
      // checks for information will be peformed here 
      $scope.account = result; 
     }, 
     function (error) { 
      // handle errors here 
      console.log(error.statusText); 
     } 
    ); 

});