javascript – 我的$scope函数中看不到变量更改

我发现状态更改事件发生时未更新到$scope函数的变量有问题,即使我看到变量在事件监听器中更新.

这是代码

angular.module('testapp')
.controller('AnotherCtrl',['$scope','$rootScope','$state',function ($scope,$rootScope,$state) {
        'use strict';
        console.log("Init prevstate.");
        var prevstate = 'null_state';
        $scope.state = prevstate;


        $rootScope.$on('$stateChangeError',function (event,toState,toParams,fromState,fromParams,error) {
                console.log("Error");
                if (toState.name === 'anotherState') {

                    console.log("Old State:" + prevstate);
                    prevstate = fromState.name;
                    console.log("New State:" + prevstate);


                }
            })

        $rootScope.$on('$stateChangeSuccess',fromParams) {
                console.log("Success");
                if (toState.name === 'anotherState') {

                    console.log("Old State:" + prevstate);
                    prevstate = fromState.name;
                    console.log("New State:" + prevstate);

                }
            })


        $scope.goBack = function () {
            //$scope.state = 'anotherState';
            console.log("goBack:" + prevstate);
            $state.transitionTo(prevstate,{arg: 'Robert'});
        };
    }]);

这是HTML模板:

<div>
<h1>Another view</h1>
<br>
<br>
State:  <span ng-model="state">{{state}}</span>
<br>
<br>
<button ng-click="goBack()">Back</button>
</div>

这是控制台输出

因此,当我按下调用函数goBack()的按钮上的按钮时,prevstate变量仍为“null_state”.

任何人都可以解释问题是什么?

审核答案后更新
我已经审核并测试了所有建议的解决方案.核心问题AFAICS与字符串类型是不可变的无关.我认为最好的答案来自@Khanh TO.首先创建控制器时,事件侦听器未初始化.这是用bootstrapping(angular.module.run)修复的.每次加载状态/视图时,控制器都会重新初始化,导致变量prevstate被重新初始化,因此监听器函数和goBack()函数使用不同的外部prevstate变量.在rootScope上存储prevstate解决了这个问题.

解决方法

根本原因是无论何时更改状态,angular都会重新初始化与当前状态关联的控制器,从而导致先前存储的状态被清除并重新初始化.

因此,解决方案是将先前状态存储在共享服务中.在这种情况下,我们可以使用$rootScope.

$rootScope.$on('$stateChangeError',error) {
                console.log("Error");
                if (toState.name === 'anotherState') {
                    $rootScope.prevstate = fromState.name;
                }
 });

 $rootScope.$on('$stateChangeSuccess',fromParams) {
                console.log("Success");
                if (toState.name === 'anotherState') {
                    $rootScope.prevstate = fromState.name;
                }
  });

  $scope.goBack = function () {
    $state.transitionTo($rootScope.prevstate,{arg: 'Robert'});
    //or $state.transitionTo($scope.prevstate,{arg: 'Robert'}); //due to scope inheritance
  };

但是,只要重新初始化AnotherCtrl,您的代码就会向$rootScope注册越来越多的事件处理程序.您的代码的第二个问题是第一次加载页面时$stateChangeSuccess事件不会触发https://github.com/angular-ui/ui-router/issues/299

您应该只在.run块中注册一次事件处理程序:

angular.module('testapp')
       .run(["$rootScope",function ($rootScope){
                $rootScope.$on('$stateChangeError',error) {
                      console.log("Error");
                      if (toState.name === 'anotherState') {
                        $rootScope.prevstate = fromState.name;
                      }
                   });

               $rootScope.$on('$stateChangeSuccess',fromParams) {
                    console.log("Success");
                    if (toState.name === 'anotherState') {
                        $rootScope.prevstate = fromState.name;
                    }
                });  
            }]);

并且只有此代码应保留在您的控制器中:

$scope.goBack = function () {
    $state.transitionTo($rootScope.prevstate,{arg: 'Robert'}); //due to scope inheritance
 };

相关文章

前言 做过web项目开发的人对layer弹层组件肯定不陌生,作为l...
前言 前端表单校验是过滤无效数据、假数据、有毒数据的第一步...
前言 图片上传是web项目常见的需求,我基于之前的博客的代码...
前言 导出Excel文件这个功能,通常都是在后端实现返回前端一...
前言 众所周知,js是单线程的,从上往下,从左往右依次执行,...
前言 项目开发中,我们可能会碰到这样的需求:select标签,禁...