Как я могу поделиться данными $ scope между состояниями в angularjs ui-router?

Без использования службы или создания наблюдателей в родительском контроллере, как можно предоставить дочерним состояниям доступ к $scope основного контроллера.

      .state("main", {
          controller:'mainController',
          url:"/main",
          templateUrl: "main_init.html"
      })  
      .state("main.1", {
          controller:'mainController',
          parent: 'main',
          url:"/1",
          templateUrl: 'form_1.html'
      })  
      .state("main.2", {
          controller:'mainController',
          parent: 'main',
          url: "/2",
          templateUrl: 'form_2.html'
      })  

Я не могу получить доступ к области mainController в дочернем состоянии - или, скорее, я получаю другой экземпляр этой области - не то, что я хочу. Я чувствую, что упускаю что-то простое. В объекте состояния есть опция конфигурации общих данных, но я не уверен, следует ли ее использовать для чего-то подобного.

70 голосов | спросил sjt003 30 TueEurope/Moscow2014-12-30T00:54:39+03:00Europe/Moscow12bEurope/MoscowTue, 30 Dec 2014 00:54:39 +0300 2014, 00:54:39

5 ответов


0

Я создал рабочий плункер , показывая, как использовать $scope и UI-Router.

Определение состояния не изменилось:

$stateProvider
    // States
 .state("main", {
      controller:'mainController',
      url:"/main",
      templateUrl: "main_init.html"
  })  
  .state("main.1", {
      controller:'mainController',
      parent: 'main',
      url:"/1",
      templateUrl: 'form_1.html'
  })  
  .state("main.2", {
      controller:'mainController',
      parent: 'main',
      url: "/2",
      templateUrl: 'form_2.html'
  })  

Но у каждого состояния может быть свой контроллер. Зачем? потому что каждый view каждого состояния получает new экземпляр определенного controller. Поэтому, пока у нас есть mainController, как показано ниже, мы можем быть уверены, что если мы перейдем к состоянию 'main.2' он будет создан дважды.

controller('mainController', function ($scope) {
  $scope.Model = $scope.Model || {Name : "xxx"};
})

Но то, что мы можем видеть здесь , это то, что мы проверяем, если $scope.Model уже существует ... и если нет, то (Родительское состояние) мы создаем его с помощью new intance {Name : "xxx"} .

Ну, я говорю: только родительское состояние будет инициировать $scope.Model. Все остальные получат это уже заполненным. Как? Ну вот ответ:

Наследование области действия только для иерархии представлений

  

Имейте в виду, что свойства области видимости наследуются только в цепочке состояний, если представления ваших состояний являются вложенными. Наследование свойств области не имеет ничего общего с вложенностью ваших состояний и имеет отношение к вложению ваших представлений (шаблонов).

     

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

Итак, как указано в документации. Поскольку наши дочерние представления вложены в родительское представление, область действия наследуется.

Общие сведения об областях

  

В AngularJS дочерняя область обычно прототипно наследуется от своей родительской области.
   ...

     

Наличие «.» в ваших моделях будет гарантировать, что наследование прототипа находится в игре.

// So, use
<input type="text" ng-model="someObj.prop1"> 
// rather than
<input type="text" ng-model="prop1">.

И это все. Мы получаем наследование от UI-Router представлений и угловых областей, а также потому, что мы умно использовали ссылочный тип ( Model ), т. Е. Иметь точку '.' в ng-model определение - теперь мы можем делиться данными

ПРИМЕЧАНИЕ: точка "." в ng-model="Model.PropertyName просто означает, что существует reference объект Model {} с некоторым свойством: PropertyName

Посмотрите рабочий пример здесь

ответил Radim Köhler 30 TueEurope/Moscow2014-12-30T08:00:01+03:00Europe/Moscow12bEurope/MoscowTue, 30 Dec 2014 08:00:01 +0300 2014, 08:00:01
0

Вы можете получить всю область действия с помощью $ rootScope . Если вам нужна только часть области действия, у ui-router есть пользовательские данные .

Вот как сделать многошаговую форму. Мне нужно, чтобы маршруты содержали информацию об их шагах в потоке.

Во-первых, у меня есть несколько маршрутов с UI-маршрутизатором:

  // Sign UP routes
  .state('sign-up', {
    abstract: true,
    url: '/sign-up',
    controller: 'SignupController',
    templateUrl: 'sign-up/index.html',
  })
  .state('sign-up.start', {
    url: '-start',
    templateUrl: 'sign-up/sign-up.start.html',
    data: { step: 0, title: 'Welcome to Mars!', },
  })
  .state('sign-up.expertise', {
    url: '-expertise',
    templateUrl: 'sign-up/sign-up.expertise.html',
    data: { step: 1, title: 'Your Expertise'},
  })

Примечание:

  • элемент data в каждом маршруте.
  • Состояние abstract имеет SignupController , Это единственный контроллер для этой многошаговой формы. abstract не требуется, но имеет смысл для этого варианта использования.

SignupController.js

angular.module('app').controller('SignupController', function($scope, $state) {
  $scope.state = $state;
});

Здесь мы получаем $state и добавляем его в $scope

Вот основной шаблон 'sign-up /index.html',

<h2>{{state.current.data.title}}</h2>

<div>This is a multi-step-progress control {{state.current.data.step}}</div>

<form id="signUpForm" name="signUpForm" novalidate>
  <div ui-view></div>
</form>

Дочерние шаблоны могут быть любыми.

ответил Michael Cole 6 PMpMon, 06 Apr 2015 12:15:11 +030015Monday 2015, 12:15:11
0

Идея заключается в том, что вы используете область в родительском наследовании>

 .state("main", {
      controller:'mainController',
      abstract: true,
      url:"/main",
      templateUrl: "main_init.html"
  })  
  .state("main.1", {
      controller:'mainController1',
      parent: 'main',
      url:"/1",
      templateUrl: 'form_1.html'
  })  
  .state("main.2", {
      controller:'mainController2',
      parent: 'main',
      url: "/2",
      templateUrl: 'form_2.html'
  })  

Если использование простое, у вас есть 3 контроллера, один из которых является общим (mainController), и у каждого представления есть свой собственный.

ответил Ben Diamant 30 TueEurope/Moscow2014-12-30T00:59:42+03:00Europe/Moscow12bEurope/MoscowTue, 30 Dec 2014 00:59:42 +0300 2014, 00:59:42
0

Если вы используете вложенные представления, просто не пишите никаких других контроллеров. Таким образом, они будут использовать одни и те же данные контроллера.

.state("main", {
            url: "/main",
            templateUrl: "templates/Ders",
            controller: "DersController as DersC"
       }).state("main.child1", {
            url: "/child1",
            templateUrl: "templates/Ders/child1"
       }).state("main.child2", {
            url: "/child2",
            templateUrl: "templates/Ders/child2"
        })
ответил Bahtiyar Özdere 29 thEurope/Moscowp30Europe/Moscow09bEurope/MoscowTue, 29 Sep 2015 22:23:27 +0300 2015, 22:23:27
0

Разве это не самое простое решение для группировки общих переменных в службу, к которой вы можете получить доступ на каждом контроллере? ...

ответил hugsbrugs 20 PMpMon, 20 Apr 2015 13:12:59 +030012Monday 2015, 13:12:59

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132