簡體   English   中英

$ scope值不會在其他控制器中更新

[英]$scope value doesn't get updated in other controller

我在更新視圖上的值時遇到問題。 讓我向您展示我的代碼,並對正在發生的事情進行一些解釋。 我知道代碼是亂七八糟的,因為我現在嘗試了很多代碼組合。

我有這個accCtrl控制器

controllers.accCtrl = function($scope, sessionFactory){
    sessionFactory.isLoggedIn().then(function(data){
        console.log(data.logged_in);
        $scope.loggedIn = data.logged_in;
    });
    $scope.logOut = function(){
        sessionFactory.logOutUser().then(function(data){
            $scope.loggedIn = data.logged_in;
        });
    }
}

控制台注銷put是false ,這個變量$ scope.loggedIn通過顯示或隱藏登錄,注冊,我的配置文件和注銷按鈕scope.loggedIn控制我的html

<div ng-controller="accCtrl">
    {{loggedIn}}
        <ul>
        <li ng-hide="loggedIn">
            <a href="#/login">
                <b>Login</b>
            </a>
        </li>
        <li ng-hide="loggedIn">
            <a href="#/register" >
                <b>Register</b>
            </a>
        </li>
        <li ng-show="loggedIn" >
            <a href="#/my_profile">
                <b >My profile</b>
            </a>
        </li>
        <li ng-show="loggedIn"> 
            <a ng-click="logOut()">
                <b>Log out</b>
            </a>
        </li>
    </ul>
</div>

現在用戶嘗試登錄,因此他點擊登錄按鈕,顯示登錄表單。 此登錄功能以loginCtrl編寫

    controllers.loginCtrl = function($scope, $http, $location, $timeout, sessionFactory){
    $scope.loginUser = function () {
        $http({
            method: 'POST',
            url: $location.protocol() + '://' + $location.host() + '/server/api/users/login',
            headers: {'Content-Type': 'application/x-www-form-urlencoded'},
            data : $.param({
                username : $scope.username,
                password : $scope.password
            })
        }).success(function(data){
                sessionFactory.isLoggedIn().then(function(data){
                    $scope.loggedIn = data.logged_in;
                });
                window.location.href="/#/home";
        });
    };
}

在他成功登錄后,他或她被重定向到主頁上,但問題是帳戶控制器中的$scope.loggedIn變量甚至沒有更新,即使console.log(data.logged_in)中的console.log(data.logged_in)被設置為true

如果用戶按下了注銷按鈕,一切正常,因為我在accCtrl中調用函數。 所以唯一的問題是當用戶登錄時,因為他在另一個控制器中執行此操作。

這里也是我的sessionFactory,萬一你不知道我如何檢查用戶是否被記錄

app.factory('sessionFactory', ['$http', '$location', function($http, $location){
    var factory = {};

    factory.logOutUser = function(){
        return $http({
            method: 'GET',
            url: $location.protocol() + '://' + $location.host() + '/server/api/users/logout'
        }).then(function successCallback(response){
            return response.data;
        },function errorCallback(response) {
            console.log('error logging out: ' + response);
        });
    }
    factory.isLoggedIn = function(){
        return $http({
            method: 'GET',
            url: $location.protocol() + '://' + $location.host() + '/server/api/users/isLoggedIn'
        }).then(function successCallback(response){
            console.log(response.data);
            return response.data;
        },function errorCallback(response) {
            console.log('Checking login failed: ' + response);
        });
    }

    return factory;
}]);

我的app.js.

var app = angular.module('app', ['ngRoute', 'ngAnimate', 'ui.sortable', 'ngFileUpload'])
app.config(function($routeProvider){
    $routeProvider.
    when('/', {controller:'homeCtrl', templateUrl:'app/templates/home.html'}).
    when('/home', {controller:'homeCtrl', templateUrl:'app/templates/home.html'}).
    when('/contact', {controller:'contactCtrl', templateUrl:'app/templates/contact.html'}).
    when('/about_us', {controller:'aboutUsCtrl', templateUrl:'app/templates/aboutUs.html'}).
    when('/cookies', {controller:'cookiesCtrl', templateUrl:'app/templates/cookies.html'}).
    when('/faqs', {controller:'faqsCtrl', templateUrl:'app/templates/faqs.html'}).
    when('/register', {controller:'registerCtrl', templateUrl:'app/templates/register.html'}).
    when('/login', {controller:'loginCtrl', templateUrl:'app/templates/login.html'}).
    when('/my_profile', {controller:'myProfileCtrl', templateUrl:'app/templates/myProfile.html'}).
    when('/trade/:param1', {controller:'tradeCtrl', templateUrl:'app/templates/trade.html'}).
    when('/user/:param1', {controller:'userCtrl', templateUrl:'app/templates/user.html'}).
    when('/swap/:param1', {controller:'subCategoriesCtrl', templateUrl:'app/templates/subCategories.html'}).
    when('/swap/:param1/:param2', {controller:'products', templateUrl:'app/templates/products.html'}).
    when('/swap/:param1/:param2/:param3', {controller:'product', templateUrl:'app/templates/product.html'}).
    otherwise({ redirectTo: '/home'});
  });

我可能要實現一些手表或一些類似的功能,但我真的不知道如果你幫我的話我會很感激。

在圖片中解釋

顯示登錄和注冊按鈕 按預期工作

用戶單擊登錄按鈕並成功登錄,但按鈕未刷新,因為在loginCtrl中發生了操作,但按鈕位於accCtrl中

在此輸入圖像描述

在瀏覽器中點擊f5后,按鈕會在accCtrl中正確更新。

在此輸入圖像描述

TLTR

一旦用戶登錄loginCtrl我必須更新$scope.loggedIn價值accCtrl

如果您需要任何其他信息,請告訴我們

出現問題是因為angularjs中的控制器只初始化一次,除非您將其設置為重新初始化。 嘗試在accCtrl提醒某些accCtrl ,即使您多次導航到該頁面,它也只會accCtrl一次警報。 點擊ctrl+f5是因為它重新初始化你的控制器。 您只需使用$window.location.reload()重新初始化控制器即可。 $window.location.reload()作用是它不僅重新加載你的控制器,還重新加載你的服務。 因為你正在使用ngRoute ,所以我認為重新初始化你的控制器是使用$window.location.reload();

.success(function(data){
                sessionFactory.isLoggedIn().then(function(data){
                    $scope.loggedIn = data.logged_in;
                });
                window.location.reload(); //the only workaround i could find with ngroute as for now.
                window.location.href="/#/home";
        });

但是,使用ui.Router$stateProvider為您提供了僅重新初始化控制器的選項,如下所示。

.state('home', {
    url: '/home',
    templateUrl: 'templates/home.html',
    controller: 'accCtrl',
    reload: true //will reload controller when state is being access
});

$state.transitionTo($state.current, {}, { reload: true, inherit: true, notify: true });

$state.go('.', null, { reload: true });

將解決重新初始化控制器的問題,這似乎是你現在的問題。

好的,你在$scope.loggedIn變量上犯了2個錯誤。

1)您感到困惑,因為控制台為$scope.loggedIn記錄了一個false和一個true值; 發生這種情況是因為promises是異步的,並且在您要求會話登錄后代碼繼續運行。

sessionFactory.isLoggedIn().then(function(data){
    console.log(data);                     (2)
    $scope.loggedIn = data.logged_in;
    console.log($scope.loggedIn);          (3)
});
console.log($scope.loggedIn);              (1) <-- executes first before promise resolves
window.location.href="/#/home";

因此,只要在承諾開始執行之前未記錄用戶,那么最后按順序但首先執行日志會自然地產生錯誤。 在promise解決后,它會產生數據並且為true。 更多關於這里這里的承諾。

2)當您使用角度框架更改范圍時,您正在使用ajax請求更改角度變量,並且需要通知角度。 angular的一個機制是使用$rootScope.$apply()顯式調用摘要周期$rootScope.$apply()或$ scope。$ apply()。 我建議你按照自己的意願開展工作。 如果你想在控制器中使用它應該這樣做:

$http({
    method: 'POST',
    url: $location.protocol() + '://' + $location.host() + '/server/api/users/login',
    headers: {'Content-Type': 'application/x-www-form-urlencoded'},
    data : $.param({
        username : $scope.username,
        password : $scope.password
    })
}).success(function(data){
    ...
    $rootScope.$apply();
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM