正在删除 angular 个控制器实例

Deleting angular controller instance

为了快速阅读,问题在 "The problem" 下进行了简化,要了解更多信息,请在回答之前继续阅读背景和注释。谢谢!

问题

我想在刷新页面或移动到不同视图然后通过导航器返回同一视图时删除控制器实例 (nav.html)。事实上,每次访问视图 X.html 时,我希望程序检查 X-controller.js 是否存在,如果确实存在,则在创建新实例之前将其删除。

我要走多远,这是我在网上找不到的 2 行解决方案,还是我正在寻找数小时的编码来完成这项工作?

背景

我的项目使用 $routeProvider 服务,而不是 ng-controller 指令。应用程序启动后,始终有两个视图,一个在顶部,您可以在其中通过控制器来回导航 "Home - Contact - Support"(逻辑上,nav.html),另一个在底部,即 "Home" 或 "Contact" 等等。

在代码开始进行大量计算之前,我对这种安排没有任何问题。控制器的同一个实例更新了比它应该多的数据,计算了以前丢弃的数据,等等。我在网上阅读过有关删除控制器的信息,但据我所知,这并不容易。

答题前注意事项:

澄清编辑

我会举例说明。假设 X.html 是由 XCtrl.js 控制的视图。 $scope.test在那个controller的开头$scope.test = 2启动,点击视图中的按钮后$scope.test变为3。另外,X视图一直显示$scope.test .所以我移动到那个视图,点击按钮,然后看到屏幕上显示了 3。然后我通过导航器移动到"Home",然后回到"X",仍然显示3。但我想要显示的是 2 个,而不是 3 个。我希望在那个控制器中更新所有内容。

解决方案

最终我使用了不同的技术来解决这个问题。保存在本地存储中的所有数据都在影响 $scope 变量(变量太多无法跟踪,我没有注意到这一点)。为了解决这个问题,一旦访问了控制器 X 控制的视图,我就清除了本地存储键 localStorageService.set('keyUsed', []);。假设一个 init 函数,那么清除本地存储的代码行放在该函数的顶部。

对于我最初认为遇到的问题,我仍在从下面的答案中标记出正确的解决方案。

Always have a '.' in your ng-models!

-- Miško Hevery (father of AngularJS)

很可能您遇到的问题是 $scope.test 而不是控制器本身。如果您的模板 x.htmltest 的值引用为 {{test}}(没有任何前缀),那么您很可能引用了错误范围的 test。它通常是由于原型范围链相互扩展并回退到原型 属性 值而发生的。在这种情况下,为 XCtrl 控制器选择一些独特的东西,并将该控制器内的所有状态放入该命名空间。例如,使用 x 作为命名空间

$scope.x = {};
$scope.x.test = 2;

而不仅仅是

$scope.test = 2;

然后在 x.html 中将值引用为

{{x.test}}

这是 Angular 最佳实践之一。

另一个可以解决您的问题的最佳实践实际上根本不使用 $scope,而是使用控制器实例本身来存储与 controllerAs 语法结合的状态:

index.html

<!DOCTYPE html>
<html ng-app="app">

  <head>
    <script data-require="angular.min.js@1.5.8" data-semver="1.5.8" src="https://code.angularjs.org/1.5.8/angular.min.js"></script>
    <script data-require="angular-route.min.js@1.5.8" data-semver="1.5.8" src="https://code.angularjs.org/1.5.8/angular-route.min.js"></script>
    <link rel="stylesheet" href="style.css" />
    <script src="script.js"></script>
  </head>

  <body ng-view>

  </body>

</html>

script.js

angular.module('app', ['ngRoute'])
  .config(['$routeProvider', function($routeProvider) {
    $routeProvider
      .when('/x', {
        controller: 'xCtrl',
        controllerAs: 'x',
        templateUrl: 'x.html'
      })
      .when('/y', {
        controller: 'yCtrl',
        controllerAs: 'y',
        templateUrl: 'y.html'
      })
      .otherwise({
        redirectTo: '/x'
      })
  }])
  .controller('xCtrl', [function() {
    var x = this;
    x.test = 2;
    x.doSomething = function() {
      x.test ++;
    };
  }])
  .controller('yCtrl', [function() {
    var y = this;
    y.hello = 'Hello';
  }])

x.html

<h1>X.html</h1>
<p>test = {{x.test}}</p>
<button ng-click="x.doSomething()">+1</button>
<a href="#/y">Link to Y</a>

y.html

<h1>Y.html</h1>
<p>{{y.hello}}</p>
<a href="#/x">Link to X</a>

现场演示:

https://plnkr.co/edit/EpUn94uWMliTaG5mvPxv?p=preview

链接:

  • 了解没有“.”的问题在您的模型中,请观看 Miško Hevery 的 this 视频。
  • 为了更好地理解 controllerAs 方法,您可以阅读 Todd Motto 的 this post。