通过历史重新加载页面时重新评估表达式

Re-evalute expressions when page reloads via history

我正在尝试找到一种方法,让 AngularJS 在通过浏览器的历史记录后退按钮重新加载页面时重新评估 state/expressions。

例如,此示例正常运行良好,但如果您选中复选框并离开页面,然后 return 通过历史返回,表达式不会重新计算并将输出 'Not Checked' 即使复选框被选中:

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.2/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myController">
    <input type="checkbox" ng-model="myCheckbox"/> 
    <p>{{myCheckbox ? 'Checked' : 'Not Checked'}}</p>  <!-- Outputs 'Checked' normally, but if page is reloaded via history back, myCheckbox can be true yet this outputs 'Not Checked' -->
</div>
<script>
    angular.module("myApp", []).controller("myController", function ($scope) {
    });
</script>

为什么不在控制器中添加一些 $onInit 逻辑以确保加载控制器时定义的状态?这将确保在启动时设置已知状态:

myApp.controller('myController', ['$scope', function($scope) {
   this.$onInit = function() {
      $scope.myCheckbox = false;
   }
}]);

如果数据需要持久化(意味着复选框状态应该与用户在重新加载页面之前留下的状态相同)您可以创建并注入 'service' 来保存和恢复数据对于您的 $scope.myCheckbox(以及任何其他需要在导航中持久存在的属性)使用一些 client-side 存储机制,例如 Web Storage Api.

这也确保无论浏览器行为如何,您的逻辑都得到尊重,这可能因浏览器而异。

// In your checkbox view, add an ng-change to track for user action
<input type="checkbox" ng-model="myCheckbox" ng-change="myCheckboxChange(myCheckbox)"/>

// in your controller define the handler for the checkbox change action    
myApp.controller('myController', ['$scope', 'PersistentDataService', function($scope, PersistentDataService) {
   this.$onInit = function() {
      $scope.myCheckbox = PersistentDataService.get('myCheckbox');
   }; 
   $scope.myCheckboxChange = function(state) {
      PersistentDataService = PersistentDataService.set('myCheckbox', state);
   };
}]);

// in a new service, define the logic to store and retrieve data from the browser    
myApp.service('PersistentDataService', function() {
   return {
      get: function(key) {
         // logic to get data from Web Storage goes here...   
      },   
      set: function(key, value) {
         // logic to set data in Web Storage goes here...
      }
   };
});