Как я могу делиться данными $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 в дочернем состоянии - вернее, я получаю еще один экземпляр этой области - не то, что я хочу. Я чувствую, что мне не хватает чего-то простого.
В объекте состояния есть опция совместного доступа к данным, но я не уверен, что это нужно использовать для чего-то вроде этого.
Ответы
Ответ 1
I создал рабочий плункер, в котором показано, как использовать $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
exsits... и если нет (родительское состояние), мы создаем экземпляр > new intance {Name : "xxx"}
.
Ну, я говорю: только родительское состояние запустит $scope.Model
. Все остальные получат это уже заполненное. Как? Ну вот ответ:
Имейте в виду, что свойства области только наследуют цепочку состояний, если представления ваших состояний вложены. Наследование свойств области не имеет ничего общего с вложением ваших состояний и всего, что связано с вложением ваших представлений (шаблонов).
Вполне возможно, что у вас есть вложенные состояния, шаблоны которых заполняют u-views в разных не-вложенных местах на вашем сайте. В этом случае вы не можете ожидать доступа к переменным области представлений родительского состояния в представлениях дочерних состояний.
Итак, как указано в документации. Поскольку наши дочерние представления вложены в родительское представление, область наследуется.
В AngularJS дочерняя область, обычно прототипически наследуемая от родительской области.
...
Наличие символа '.' в ваших моделях будет гарантировать, что прототипное наследование находится в игре.
// So, use
<input type="text" ng-model="someObj.prop1">
// rather than
<input type="text" ng-model="prop1">.
И что это. Мы получаем наследование из UI-Router
представлений и angular областей, и потому, что мы разумно использовали ссылочный тип (Model
), т.е. Имели '.'
точку в определении ng-model
- мы можем обмениваться данными сейчас
ПРИМЕЧАНИЕ: с точкой. в ng-model="Model.PropertyName
просто означает, что существует объект reference
Model {}
с некоторым свойством: PropertyName
Проверьте рабочий пример здесь
Ответ 2
Вы можете получить весь объем через $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;
});
Здесь мы получаем ui-router $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>
Детские шаблоны могут быть любыми, как им нравится.
Ответ 3
Идея состоит в том, что вы используете область действия в родительском → дочернем наследовании:
.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), и у каждого представления есть свой собственный.
Ответ 4
Если вы используете вложенные представления, просто не записывайте никаких других контроллеров. Таким образом, они будут использовать одни и те же данные контроллера.
.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"
})
Ответ 5
Не самое простое решение для группировки общих переменных в службу, к которой вы можете получить доступ в каждом контроллере?...