微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐