Javascript AngularJS用户界面路由器用户界面sref导致;未捕获类型错误:无法读取属性';0';“未定义”的定义;错误

Javascript AngularJS用户界面路由器用户界面sref导致;未捕获类型错误:无法读取属性';0';“未定义”的定义;错误,javascript,angularjs,angular-ui-router,page.js,Javascript,Angularjs,Angular Ui Router,Page.js,我有一个angularJS组件,使用ui路由器和两个简单的路由状态 export default function Routes($stateProvider, $urlRouterProvider, $locationProvider) { $stateProvider .state('details', { url: '/', template: '<div>...</div>' })

我有一个angularJS组件,使用ui路由器和两个简单的路由状态

export default function Routes($stateProvider, $urlRouterProvider, $locationProvider) {
    $stateProvider
        .state('details', {
          url: '/',
          template: '<div>...</div>'
        })
        .state('pdf', {
          url: '/viewpdf',
          template: '<pdf-viewer></pdf-viewer>'
        });

    $urlRouterProvider.otherwise(function ($injector, $location) {
        var $state = $injector.get("$state");
        $state.go("details");
    });
}
间歇性地,当我按下BacktoDetails按钮时,它会从page.js抛出一个错误,并且不会更改路由状态

查找我得到的错误源:(page.js:208)

url和视图位于
/viewpdf
。如果我再等几秒钟,再按一下后退按钮,它就会正常工作

是什么导致了这种行为,我如何修复它

编辑
我应该澄清,当我提到后退按钮时,我指的是
/viewpdf
视图中的返回到详细信息按钮,而不是浏览器后退按钮。“浏览器后退”按钮未显示该错误。

这可能会使其正常工作:

$state.go('state',{},{
    reload: true
});
重新加载
文档:

您可能还需要添加一个
.then()
以检查您的
pdf
状态在更改回
详细信息
状态时是否仍在加载:

$state.go(..
    .then(
        onfulfilled,
        onrejected
    );
then()
Docs:

更新:

如果其他导航按钮放置在州组件内,则本节文档可能会有用

在这个侦听器中,您可以对导航按钮执行类似
$scope.loaded=true
的操作,禁用
ng

此测试代码配置导航控件的指令,并禁用它,直到加载视图的DOM:

angular.module('app',['ui.router'])
  .component('componentHome', {
    template: '<div>Home Page Contents...</div>',
    controller: ['$scope','$state','$rootScope',function($scope,$state,$rootScope){
      $scope.loaded = false;
      $rootScope.$on('$viewContentLoaded',
      function(event, viewConfig){
          $scope.loaded = true;
      });
    }]
  })
  .component('componentA', {
    template: '<div><go></go></div>',
    controller: ['$scope','$state','$rootScope',function($scope,$state,$rootScope){
      $scope.loaded = false;
      $rootScope.$on('$viewContentLoaded',
      function(event, viewConfig){
          $scope.loaded = true;
      });
      $scope.stateName = 'b';
      $scope.stateLabel = 'B';
    }]
  })
  .component('componentB', {
    template: '<div><go></go></div>',
    controller: ['$scope','$state','$rootScope',function($scope,$state,$rootScope){
      $scope.loaded = false;
      $rootScope.$on('$viewContentLoaded',
      function(event, viewConfig){
          $scope.loaded = true;
      });
      $scope.stateName = 'a';
      $scope.stateLabel = 'A';
    }]
  })
  .directive('go',['$state',function($state){
    return {
      restrict: 'E',
      template: '<button ng-disabled="!loaded" state="stateName">Go to Page {{ stateLabel }}</button>',
      link: function(scope,element){
        element.on('click',function(e){
          $state.go(scope.stateName,{},{
            reload: true
          }).then(
            function(){
              // fulfilled
            },
            function(){
              // rejected
            }
          );
        });
      }
    };
  }])
  .config(function($stateProvider){
    $stateProvider.state('/',{ url: '/', component: 'componentHome' });
    $stateProvider.state('a',{ url: '/a', component: 'componentA' });
    $stateProvider.state('b',{ url: '/b', component: 'componentB' });
  })
;
angular.module('app',['ui.router']))
.component(“componentHome”{
模板:“主页内容…”,
控制器:['$scope','$state','$rootScope',函数($scope,$state,$rootScope){
$scope.loaded=false;
$rootScope.$on(“$viewContentLoaded”,
函数(事件、视图配置){
$scope.loaded=true;
});
}]
})
.component('componentA'{
模板:“”,
控制器:['$scope','$state','$rootScope',函数($scope,$state,$rootScope){
$scope.loaded=false;
$rootScope.$on(“$viewContentLoaded”,
函数(事件、视图配置){
$scope.loaded=true;
});
$scope.stateName='b';
$scope.stateLabel='B';
}]
})
.组件(“组件B”{
模板:“”,
控制器:['$scope','$state','$rootScope',函数($scope,$state,$rootScope){
$scope.loaded=false;
$rootScope.$on(“$viewContentLoaded”,
函数(事件、视图配置){
$scope.loaded=true;
});
$scope.stateName='a';
$scope.stateLabel='A';
}]
})
.directive('go',['$state',function($state){
返回{
限制:'E',
模板:“转到页面{{stateLabel}}”,
链接:功能(范围、元素){
元素上('click',函数(e){
$state.go(scope.stateName,{}{
重新加载:正确
}).那么(
函数(){
//履行
},
函数(){
//拒绝
}
);
});
}
};
}])
.config(函数($stateProvider){
$stateProvider.state('/',{url:'/',component:'componentHome'});
$stateProvider.state('a',{url:'/a',component:'componentA'});
$stateProvider.state('b',{url:'/b',component:'componentB'});
})
;
使用html:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <script src="jquery.js"></script>
    <script src="angular.js"></script>
    <script src="angular-ui-router.min.js"></script>
    <style>
      .active{ border: 1px dashed red; }
    </style>
  </head>
  <body ng-app="app">
      <a ui-sref="/"  ui-sref-active="active">Home Page</a>
      <a ui-sref="a" ui-sref-active="active">Page A</a>
      <a ui-sref="b" ui-sref-active="active">Page B</a>
      <div>
        <ui-view></ui-view>
      </div>
    <script src="app.js"></script>
  </body>
</html>

.active{边框:1px红色虚线;}
主页
A页
B页

两个问题:1)什么是page.js?2) 你为什么不直接使用
$urlRouterProvider.否则('details')因为你没有在其他函数中使用任何高级功能?我没有显式添加page.js,它看起来像是ui路由器的依赖项。另外,还添加了回调以解决其他一些路由问题(我现在不记得是哪个了?)。这是问题的简化版本,而不是整个应用程序。此外,我的理解是,
ui sref
应该以
否则
不会起作用的方式设置路由状态。“后退”按钮仅加载“否则”状态是不正确的。然后我是否需要将ui sref更改为单击处理程序调用以使用$state.go返回按钮?@mWatch取决于您的实现。我用一些额外的文档和测试代码更新了答案。
$state.go(..
    .then(
        onfulfilled,
        onrejected
    );
$rootScope.$on('$viewContentLoaded',
  function(event, viewConfig){
      // Access to all the view config properties.
      // and one special property 'targetView'
      // viewConfig.targetView
  });
angular.module('app',['ui.router'])
  .component('componentHome', {
    template: '<div>Home Page Contents...</div>',
    controller: ['$scope','$state','$rootScope',function($scope,$state,$rootScope){
      $scope.loaded = false;
      $rootScope.$on('$viewContentLoaded',
      function(event, viewConfig){
          $scope.loaded = true;
      });
    }]
  })
  .component('componentA', {
    template: '<div><go></go></div>',
    controller: ['$scope','$state','$rootScope',function($scope,$state,$rootScope){
      $scope.loaded = false;
      $rootScope.$on('$viewContentLoaded',
      function(event, viewConfig){
          $scope.loaded = true;
      });
      $scope.stateName = 'b';
      $scope.stateLabel = 'B';
    }]
  })
  .component('componentB', {
    template: '<div><go></go></div>',
    controller: ['$scope','$state','$rootScope',function($scope,$state,$rootScope){
      $scope.loaded = false;
      $rootScope.$on('$viewContentLoaded',
      function(event, viewConfig){
          $scope.loaded = true;
      });
      $scope.stateName = 'a';
      $scope.stateLabel = 'A';
    }]
  })
  .directive('go',['$state',function($state){
    return {
      restrict: 'E',
      template: '<button ng-disabled="!loaded" state="stateName">Go to Page {{ stateLabel }}</button>',
      link: function(scope,element){
        element.on('click',function(e){
          $state.go(scope.stateName,{},{
            reload: true
          }).then(
            function(){
              // fulfilled
            },
            function(){
              // rejected
            }
          );
        });
      }
    };
  }])
  .config(function($stateProvider){
    $stateProvider.state('/',{ url: '/', component: 'componentHome' });
    $stateProvider.state('a',{ url: '/a', component: 'componentA' });
    $stateProvider.state('b',{ url: '/b', component: 'componentB' });
  })
;
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <script src="jquery.js"></script>
    <script src="angular.js"></script>
    <script src="angular-ui-router.min.js"></script>
    <style>
      .active{ border: 1px dashed red; }
    </style>
  </head>
  <body ng-app="app">
      <a ui-sref="/"  ui-sref-active="active">Home Page</a>
      <a ui-sref="a" ui-sref-active="active">Page A</a>
      <a ui-sref="b" ui-sref-active="active">Page B</a>
      <div>
        <ui-view></ui-view>
      </div>
    <script src="app.js"></script>
  </body>
</html>