Как сохранить данные области при изменении состояний с помощью ui-router? - PullRequest
0 голосов
/ 04 февраля 2019

Я создаю одностраничное веб-приложение, используя AngularJS с ui-router.У меня два разных состояния, один родитель и один ребенок.В родительском состоянии «точки» пользователи могут делать выбор из ng-repeat, и их выбор отображается с использованием области действия.

Когда пользователь делает выбор, я запускаю функцию ng-click, котораяиспользует $ state.go для загрузки «подробностей» дочернего состояния.Я хотел бы загрузить их выбор в дочернем состоянии, но похоже, что данные области исчезли?

Я пытался использовать один и тот же контроллер для каждого состояния.ui-sref также не работает.

Из родительского состояния 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.

1 Ответ

0 голосов
/ 04 февраля 2019

Вы должны понимать, как работает наследование прототипов.Когда родитель помещает значение свойства в область с помощью

$scope.value = 'something';

В дочернем компоненте при доступе к $ scope.value цепочка наследования найдет $ scope.value.

Если дочернийустанавливает

$scope.otherValue = 'something';

Если следует по цепочке наследования, не находит значение otherValue и создает свойство в дочерней области, а не в унаследованном прототипе, поэтому родительский компонент и любые другие дочерние элементы родителя непосмотрите.

Вы можете использовать то, что называется правилом точек наследования прототипов.Если родитель создает объект в области, называемый чем-то вроде данных

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

Теперь, если дочерний объект помещает свойство в объект данных

$scope.data.otherValue = 'something';

Он ищет объект данных, находитоно находится в цепочке наследования, и поскольку вы добавляете свойство к экземпляру объекта, оно становится видимым для родителя и всех потомков родителя.

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.

Для обмена данными между контроллерами вы используете сервис, который внедряется в оба контроллера.,У вас есть коллекция точек в службе и вы используете параметр маршрута, чтобы определить, какую точку должен использовать другой контроллер, или у вас есть место в службе с именем currentSpot, установленное другим контроллером.

Службы - это одноэлементный объект, который высоздать на уровне модуля, а затем все контроллеры, которые запрашивают их в своем списке зависимостей, получают один и тот же экземпляр.Они являются предпочтительным способом обмена данными между контроллерами, иерархии $ scope неизбежно приводят к путанице, поскольку их прототипное наследование может сбивать с толку.Дочерняя область $ $ унаследована по прототипу от его родителя, похоже, вам следует обмениваться данными, но когда дочерний контроллер устанавливает свойство, оно невидимо для родителя.

Вы изучаете устаревший способ углового программирования,Внедрение $ scope больше не рекомендуется.Посмотрите на использование компонентов.Компоненты являются оболочкой для контроллера с изолированной областью действия и с использованием синтаксиса contollerAs.Изолированные области видимости значительно упрощают понимание того, откуда поступают данные.

Посмотрите на мой ответ на этот вопрос

Попытка активировать флажок из контроллера, который находится в другом контроллере

...