使用 ui-router 更改状态时如何保留示波器数据?

How to preserve scope data when changing states with ui-router?

我正在使用 AngularJS 和 ui-router 构建单页网络应用程序。我有两种不同的状态,一种 parent 和一种 child。在 parent 状态下,'spots',用户可以从 ng-repeat 中进行选择,他们的选择会使用范围显示。

当用户做出选择时,我 ng-click 触发一个函数,该函数使用 $state.go 加载 child 状态 'details'。我想在 child 状态下加载他们的选择,但范围数据似乎不见了?

我试过为每个状态使用相同的控制器。 ui-sref 也不行。

来自 parent 状态 HTML 模板

<div class="card-column mx-0" data-ng-click="makeSelection = true">

 <div class="card mx-0 mb-3 ng-scope" data-ng-click="showSpot(spot);" data-ng-repeat="spot in spots | filter:{'game':gameID} | filter:{'walking':distanceID} | filter:{'vehicle':vehicleID} | orderBy:'price' | filter as results">
   <div class="row no-gutters">

    <div class="col-sm-12 col-md-3 col-lg-3">
      <img src="{{ spot.image }}" alt="parking spot"/>
    </div>

    <div class="col-sm-12 col-md-9 col-lg-9">
      <div class="card-body px-4 pt-4">

        <h6 class="text-small-extra text-muted font-weight-normal text-uppercase"><span style="letter-spacing: .05rem;">{{ spot.type }}</span></h6>

        <h5 class="card-title">{{ spot.address }}</h5>

        <h4 class="text-muted float-md-right">${{ spot.price }}<span style="font-size: 1rem; font-weight: 400">/day</span></h4>

      </div>

    </div>

  </div>

</div>

来自控制器的片段

$scope.showDetails = function() {
  $state.go('spots.details'); //my route...
}

$scope.showSpot = function(spot) {
  $scope.spot = spot;
  $scope.showDetails();
}

来自 app.js

的片段
.config(function($stateProvider, $urlRouterProvider) {

$urlRouterProvider.otherwise("/")

$stateProvider
.state('spots',{
  url: '/',
  templateUrl: "/parkit/master/spots-available.html",
  controller: 'parkitController'
})
.state('details', {
  parent: 'spots',
  url: '/details',
  templateUrl: '/parkit/master/details.html',
})
.state('statetwo', {
  url: '/statetwo',
  template: '<h1>State Two</h1>',
  controller: 'parkitController'
});

})

我希望用户选择在 ng-click 触发后显示在 child 状态。

您需要了解原型继承的工作原理。当 parent 将 属性 值放在范围

上时
$scope.value = 'something';

在 child 组件中,如果您访问 $scope.value,继承链将找到 $scope.value.

如果 child 设置

$scope.otherValue = 'something';

If 遵循继承链,找不到 otherValue 的值并在 child 范围内创建一个 属性,而不是继承的原型,因此 parent 组件和任何其他child仁的parent没看到。

你可以使用所谓的原型继承的点规则。如果 parent 在作用域上创建一个 object 类似 data

$scope.data = { value: 'something' };

现在如果 child 在数据 object

上放置 属性
$scope.data.otherValue = 'something';

它查找数据 object,在继承链中找到它,因为您要将 属性 添加到 object 的实例,所以它对 parent 和 parent.

的任意 children

let parent = {
  value: 'some value',
  data: { value: 'some value' }
};

let child = Object.create(parent);

console.log(child.value); // Finds value on the prototype chain

child.newValue = 'new value'; // Does not affect the parent

console.log(parent.newValue);

child.data.newValue = 'new value'; // newValue is visible to the parent

console.log(parent.data.newValue);

简短的回答是永远不要注入 $scope 并使用 controllerAs 语法。

要在控制器之间共享数据,您可以使用注入到两个控制器的服务。您在服务上收集了 spots 并使用路由参数来标识另一个控制器应该使用哪个 spot 或在另一个控制器设置的名为 currentSpot 的服务上有一个位置。

服务是您在模块级别创建的单例 object,然后所有在其依赖项列表中请求它们的控制器都会获得相同的实例。它们是在控制器之间共享数据的首选方式,$scope 层次结构必然会导致混淆,因为它们的原型继承性质可能会造成混淆。 child $scope 原型继承自它的 parent,这看起来你应该共享数据但是当 child 控制器设置 属性 它对 parent.

您正在学习一种过时的 Angular 编程方式。注入 $scope 不再是推荐的方式。看看使用组件。组件是具有隔离范围并使用 contollerAs 语法的控制器的包装器。隔离范围使了解数据来源变得更加清晰。

看看我对这个问题的回答