6
votes

En attente de la valeur de $ Rootscope pour résoudre dans une charge angulaire avant la charge de la page

Donc, je cours dans ce problème où j'utilise NGView et j'ai une barre de navigation statique tout au long de la présente:

'use strict';

app.factory('Auth',
    function($rootScope, $location, $firebase, $firebaseSimpleLogin, firebaseUrl) {

    var refDownload = new Firebase(firebaseUrl + 'housemates');

    var sync = $firebase(refDownload); 

    var ref = sync.$asObject();

    var authClient = new FirebaseSimpleLogin(refDownload, function(error, user) {
        if (error) {
            incorrectLogin(error.code);
        }
        if (user) {
            // 1
            // user authenticated
            correctLogin(user.id);
        } else {
            // user is logged out
            // $rootScope.signedIn = false;
        }
    });

    var Auth = {

        housemates: ref,

        changeColor: function(color) {
            var id = $rootScope.currentUser.id.toString();
            refDownload.child(id).update({ color: color });
            $rootScope.currentUser.color = color;
        },


        create: function(authUser, usr) {
            refDownload.child(authUser.id).set({
                initials: usr.initials,
                email: authUser.email,
                password: usr.password,
                color: 'Blue',
                id: authUser.id,
                uid: authUser.uid,
                rememberMe: true,
            });

        },

        // 3
        findById: function(id) {
            refDownload.on('value', function(snapshot) {
                var userObject = snapshot.val();
                // 4 - sets currentUser
                //$rootScope.currentUser = userObject[id];
                var currentUser = userObject[id];
                Auth.setUser(currentUser);
                // $rootScope.signedIn = true;
            }, function (error) {
                console.log(error);
            });
        },

        login: function(user) {
            authClient.login('password', {
                email: user.email,
                password: user.password,
                rememberMe: true
            });
        },

        logout: function() {
            delete $rootScope.currentUser;
            delete $rootScope.signedIn;
            delete $rootScope.error;
            return authClient.logout();
        },

        register: function(user) {
            var userSimple = user;
            authClient.createUser(user.email, user.password, function(error, user) {
                if(!error) {
                    var userComplex = user;
                    Auth.login(userSimple);
                    Auth.create(userComplex, userSimple);
                    return user;
                } else {
                    console.log(error);
                }
            });

        },

        setUser: function(aUser) {
            console.log('setuser ran');
            $rootScope.currentUser = aUser;
            console.log('setUser: ' + $rootScope.currentUser);
        },

        isLoggedIn: function() {
            console.log($rootScope.currentUser);
            return ($rootScope.currentUser) ? $rootScope.currentUser : false;
        },


    };

    // 2
    function correctLogin(id) {
        Auth.findById(id);
    }

    function incorrectLogin(error) {
        alert(error);
        $rootScope.error = error;
    }

    return Auth;


});


12 commentaires

Peut-être que le Ngcloak pourrait vous aider. Ou un délai d'attente peut-être ...


J'ai essayé de mettre Ng-Cloak sur le top DIV dans la vue NAV.HTML, mais cela ne résout pas le problème.


Vous devez également essayer un service au lieu de $ rootscope .


J'ai commencé à utiliser un service pour mes détails de l'utilisateur actuels, mais j'appelle les informations d'objet utilisateur sur littéralement toutes les pages et sur les vues - N'est-ce pas le cas d'utilisation pour $ rootscope? En outre, cela ne traite pas de mon problème.


Il n'y a pas de cas d'utilisation pour $ rootscope sauf les diffusions peut-être, et vous devriez éviter les personnes aussi. Un service est persistant (sorte d'un singleton) donc il n'y a pas de mal dans $ portée.foo = someervice.getsomedata (); .


De plus, pour Adressez le problème , seulement vous savez quelles charges $ rootscope.signedin . Dans ce code, vous pouvez également $ ROOTSCOPE.USEROCALED = FALSE; __load les données __. onsuccessdo: $ rootscope.userloadrad = true; , puis ng-show = "utile chargé" dans la barre de navigation.


Merci pour le conseil, je vais travailler à convertir mes objectifs de $ rootscope en objets de service à partir desquels ils sont venus. Avez-vous des conseils sur ma situation actuelle?


@HIMMEL Lisez les docs pour NG-Cape, pour le faire fonctionner correctement dans tous les cas, vous devez faire des trucs avec lesquels vous devez faire des trucs, de sorte que l'élément que vous utilisez peut être caché dès que possible sur la charge de la page. Une autre approche serait de jeter un coup d'œil au routeur d'interface utilisateur angulaire - c'est comme Ngview sur les stéroïdes. Il a une belle fonctionnalité «résolution» qui ne montrera pas la vue jusqu'à ce que votre promesse soit résolue.


@SergiuparaschivvIV mon $ rootscope.signedIn retourner fonctionnellement vrai ou faux. Je suis donc en cours d'exécution ng-show = "Signédin" à mon avis. Mon problème est que $ rootscope.signedin est faux, non défini, jusqu'à ce que le service charge les données. Donc, il affiche brièvement la barre NAV avec la valeur "False" NG-Show jusqu'à ce que l'utilisateur clique sur quelque chose.


@Sunild. Je vais jeter un coup d'œil au routeur UI pour une utilisation future, mais comme je suis en train d'utiliser Ngview, je ne cherche pas encore à faire une refonte.


Semble ok au premier coup d'œil (bien que je n'ai jamais utilisé de firebase), mais pour être sûr, pls mettre {{ishaden}} quelque part dans la NAV.HTML et activer la console de développeur chrome pour voir si une erreur a brisé le code JavaScript.


Je mets {{ishaden}} dans la navigation de navigation et la connexion ne semble pas modifier la valeur. Cependant, lorsque je clique sur un élément de la barre NAVBAR, puis Mises à jour de la valeur Ishidden. Je me semble être un problème de contrôleur. Dans mon index.html J'appelle la vue NAV et la NAV CTRL. Mais lorsque la page de connexion s'ouvre, elle utilise AuthCtrl plutôt que NavCtrl. Cela pourrait-il être le problème? Puis-je envelopper mes divs dans index.html autour du NG-Inclure? Comment puis-je modifier la valeur ishadée dans la portée de navigation d'autres contrôleurs? Ne devrait-il pas changer automatiquement avec les connexions / déconnages du service?


3 Réponses :


6
votes

avec un peu de $ CoSoScope. $ Diffusion et NG-Masquer dans le menu, cela pourrait être facilement accompli. Voir ce Plunker

Le HTML: P>

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope, $rootScope) {
  $scope.login = function() {
    $rootScope.$broadcast("login");
  }

  $scope.logout = function() {
    $rootScope.$broadcast("logout");
  }
});

app.controller('NavCtrl', function($scope) {
  $scope.isHidden = true;
  $scope.$on('login', function() {
    console.log("logged in");
    $scope.isHidden = false;
  });

  $scope.$on('logout', function() {
    console.log("logged out");
    $scope.isHidden = true;
  });
});


10 commentaires

J'ai diffusé avec succès l'événement de connexion / déconnexion au contrôleur NAVCTRL, cependant, sur la connexion à l'utilisateur réussi, la barre NAV ne change pas tant que l'utilisateur clique sur quelque chose.


Qu'entendez-vous par «La barre NAVBL ne change pas tant que l'utilisateur clique-t-il quelque chose»? Comme j'ai compris votre question, vous souhaitez afficher ou masquer la barre NAV en fonction du statut de connexion de l'utilisateur.


La diffusion semble être enregistrée, car NAVCTRL Console.logs "connecté", mais la vue ne met pas à jour pour une raison quelconque lorsque l'utilisateur se connecte ... L'utilisateur doit cliquer sur quelque chose avant la vue de la barre NAVBAR.


Avez-vous essayé mon échantillon de plumker? Est-ce le comportement que vous voulez?


C'est le comportement que je voulais. Toutefois, la diffusion ne change que l'affichage / réglage de l'état sur la charge de la page et non lorsque l'utilisateur se connecte sous forme de changement instantané.


Signification, la barre NAV reflète les modifications ou «obtient» l'état lorsque je charge correctement l'application et que la diffusion incendie, mais lorsque je me connecte, la diffusion incendie, mais l'état ne change pas.


Je ne sais pas comment vous gérez exactement votre processus de connexion, mais il devrait suivre le code de l'échantillon que j'ai écrit. Lorsque l'utilisateur est authentifié à la diffusion, un événement "Connexion" et dans le contrôleur où la vue parent de la barre NAVBAR est un événement "ON" qui attend l'événement "Connexion" à envoyer. Ensuite, définissez une variable ("cachée") à FALSE et raccrochez-la jusqu'à la directive NG-Masquer sur la balise NAVBAR.


Votre exemple a été très utile, je l'ai mis en œuvre et cela a fonctionné comme prévu. Sur l'authentification de l'utilisateur, le service diffuse 'login', la portée choisit cette opération et des journaux connectés 'à la console. Donc, à tout moment, un utilisateur est authentifié, ou déconnecté ou connecté ou autre, l'événement de diffusion incendie comme prévu. Mais lorsque je me connecte manuellement, la vue ne met pas à jour avec le "ishacident". Il enregistre seulement après que l'utilisateur clique sur autre chose.


Peut-être que vous pouvez fournir un exemple de code. Je suis sûr que cela aidera. Je suppose que vous avez un problème de synchronisation. Peut-être vous authentifiez-vous contre un service de contrôle via un appel HTTP et cela prend un certain temps, vous devez donc utiliser des promesses de savoir quand l'appel est terminé.


Veuillez consulter la mise à jour ci-dessus, j'ai fourni des exemples du service qui obtient les données, le $ Diffusion dans le service, le contrôleur qu'il est injecté et la vue. J'ai également montré le contrôleur qui est lié à la vue Modèle de connexion.



1
votes

OK, si la façon dont j'ai suggéré de ne pas travailler pour vous, voici une deuxième solution possible ( Plunker )

L'idée de base est d'avoir un service (dans ce cas une usine) dans laquelle vous définissez le nom d'utilisateur connecté, puis dans le contrôleur NAV Utilisez $ watch pour regarder les modifications apportées au statut d'authentification. dans le service. Et le code: xxx

le javascript: xxx

et le service: xxx < / pré>


3 commentaires

Hmm, j'ai essayé d'ajouter la fonction Isloggedin avec le contrôleur $ watch , mais mon service d'authentification est plus complexe que de définir immédiatement l'utilisateur comme utilisateur actuel. Il doit s'authentifier, puis trouver l'utilisateur par son numéro d'identification. Je posterai une usine complète ci-dessus.


Eh bien, je soupçonnai qu'il y a une certaine complexité dans votre code d'authentification qui empêche le code de travailler. Si vous avez une autre étape dépendante (en trouvant un utilisateur par ID), vous devez utiliser des promesses. Quoi qu'il en soit, je suis content que vous ayez résolu votre problème.


Merci pour tout votre aide.



0
votes

@zszep $ $ Broadcast Réponse a résolu le problème avec une mise en garde. Il était nécessaire d'ajouter $ de portée. $ Apply () Après chacune des commandes $ de portée. Cela a forcé une page actualisée de la sorte et la vue de navigation de navigation mise à jour.


0 commentaires