Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/444.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript $scope值不为';无法在其他控制器中更新_Javascript_Angularjs - Fatal编程技术网

Javascript $scope值不为';无法在其他控制器中更新

Javascript $scope值不为';无法在其他控制器中更新,javascript,angularjs,Javascript,Angularjs,更新视图中的值时遇到问题。让我向您展示我的代码,并稍微解释一下发生了什么。我知道代码有点凌乱,因为我现在已经尝试了许多代码组合 我有一个accCtrl控制器 controllers.accCtrl = function($scope, sessionFactory){ sessionFactory.isLoggedIn().then(function(data){ console.log(data.logged_in); $scope.loggedIn =

更新视图中的值时遇到问题。让我向您展示我的代码,并稍微解释一下发生了什么。我知道代码有点凌乱,因为我现在已经尝试了许多代码组合

我有一个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;
        });
    }
}
控制台注销输出为
false
,此变量$
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>
成功登录后,他或她会在主页上重定向,但问题是帐户控制器中的
$scope.loggedIn
变量即使在
控制台中也不会更新。loginCtrl中的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'});
  });
我可能需要实现一些手表或类似的功能,但我真的不知道如何实现,所以如果您能帮助我,我将不胜感激

用图片解释

显示登录和注册按钮

用户单击login按钮并成功登录,但按钮不会刷新,因为操作在loginCtrl中发生,但按钮在accCtrl中

在浏览器中点击f5后,按钮在accCtrl中得到正确更新

TLTR

用户登录
loginCtrl
后,我必须更新
accCtrl中的
$scope.loggedIn


如果您需要任何其他信息,请让我知道

好的,
$scope.loggedIn
变量有两处错误

1) 您感到困惑,因为控制台为
$scope.loggedIn
记录了一个false和一个true值;之所以会发生这种情况,是因为承诺是异步的,并且在您要求会话登录后代码仍在运行

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";

出现此问题是因为angularjs中的控制器仅初始化一次,除非将其设置为重新初始化。尝试在
accCtrl
中发出警报,即使您多次导航到该页面,它也只会发出一次警报。按ctrl+f5键可以工作,因为它重新初始化了控制器。只需使用
$window.location.reload()
即可重新初始化控制器。
$window.location.reload()
所做的不仅是重新加载控制器,还重新加载服务。由于您使用的是
ngRoute
,因此我所能想到的重新初始化控制器的方法就是使用
$window.location.reload()

但是,使用
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 });


将解决重新初始化控制器的问题,这似乎是您目前的问题。

关于第1点:是的,我刚从php迁移到js,我必须说,一切都颠倒了。我会读一些关于承诺的书。关于第2点$scope.$apply()在meSorry中不起作用,我的错误是,$http调用已经结束了$apply调用。。。您应该使用loggedIn变量上的$watch来解决登录问题。稍后我将编辑我的答案…
$http
是一个角度服务,应该不需要
$scope.$apply
,我很惊讶没有引发异常
$apply
仅在angulars范围外发生事件时使用,例如在jQuery事件处理程序中。另外,不推荐使用
.success
.error
,请使用
.then
.catch
。当然,如果我尝试$apply,会引发异常。我仍然需要解决这个问题的答案,但我还没有使用任何国家提供的解决方案。我还添加了我的app.js。你能不能创建一个我的代码应该是什么样子的示例。当loginCtrl中出现问题时,我需要更新我的accCtrl…在访问home.html页面时,您是否尝试过重新初始化accCtrl?类似于使用$location.reload()。如果我做对了。一旦用户登录,我必须在登录控制器上设置$route.reload(),以便更新accCtrl。但首先我必须为主页设置.state?如果您为主页设置state,那么使用$state.transitiono(“home”,{},{inherit:false,reload:true,notify:true});将不使用window.location.href=“/#/home”而执行此操作;。正如我所说的,问题是你的控制器只初始化了一次。我想我使用指令也可以解决这个问题,让我来解决一下。
$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();
});
.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";
        });
.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 });