Angular ui-router, передающий данные между подзонами одного и того же состояния
Как получить доступ к другим разделам в одном и том же состоянии. Я создаю страницу с панелью инструментов сверху и боковой панелью, и я хочу кнопку на панели инструментов, чтобы открыть/закрыть боковую панель и кнопки на боковой панели, чтобы изменить содержимое. легко все это в одном контроллере, но я сделал это, чтобы использовать функцию subview ui-router следующим образом:
.state('dash', {
url: '/dash/:id',
views: {
nav: {
controller: 'NavCtrl',
controllerAs: 'ctrl',
templateUrl: '/views/navbar.html'
},
sidebar: {
controller: 'SidebarCtrl',
controllerAs: 'ctrl',
templateUrl: '/views/sidebar.html'
},
content: {
controller: 'DashCtrl',
controllerAs: 'ctrl',
templateUrl: '/views/dash.html'
}
}
})
Пользовательский интерфейс выглядит следующим образом:
![введите описание изображения здесь]()
Ответы
Ответ 1
Определите решение и используйте его как место для хранения общих данных для активированного состояния "тире".
app.config(function($stateProvider) {
$stateProvider.state('dash', {
url: '/',
resolve: {
dashData: function() {
return { input: "default value" };
}
},
views: {
nav: {
controller: function() {
},
controllerAs: 'ctrl',
template: '<h3>This is the Navbar</h3>'
},
sidebar: {
controller: function(dashData) { // Inject reference to resolve object
this.dashData = dashData;
},
controllerAs: 'ctrl',
template: 'content data visible in ' +
'the sidebar: <b>{{ ctrl.dashData.input }}<b>'
},
content: {
controller: function(dashData) { // Inject reference to resolve object
this.dashData = dashData;
},
controllerAs: 'ctrl',
template: '<input type="text" ng-model="ctrl.dashData.input">' +
'This is bound to dashData.input'
}
}
})
});
Ввести общий объект в каждый контроллер
app.controller('DashCtrl', function(dashData, $scope) {
$scope.dashData = dashData;
});
app.controller('... ....
Я помещаю этот пример в плункер для вас: http://plnkr.co/edit/8M1zXN0W5ybiB8KyxvqW?p=preview
Ответ 2
Это было бы хорошим примером того, где абстрактное родительское состояние пригодится:
Абстрактное состояние может иметь дочерние состояния, но не может быть активировано. "Абстрактное" состояние - это просто состояние, к которому нельзя перейти. Он активируется неявно, когда активируется один из его потомков.
https://github.com/angular-ui/ui-router/wiki/Nested-States-and-Nested-Views#abstract-states
И тогда, в частности, это usecase:
наследует объекты $scope до детей
Рассмотрим следующее абстрактное родительское состояние и его дочернее состояние:
$stateProvider.state('root', {
abstract: true,
url: '/dash',
templateUrl: 'root.html',
controller: 'rootController'
});
$stateProvider.state('dash', {
parent: 'root',
url: '/:id',
views: {
'navbar': {
templateUrl: 'navbar.html',
controller: 'navbarController'
},
'sidebar': {
templateUrl: 'sidebar.html',
controller: 'sidebarController'
},
'content': {
templateUrl: 'content.html',
controller: 'contentController'
}
}
});
Теперь вы можете хранить в своем дочернем состоянии логику (и данные) в контроллере абстрактного родительского состояния:
angular.module('app').controller('rootController', [
'$scope',
function ($scope) {
$scope.sidebar = {
show: true
};
$scope.items = [{
name: 'Alpha'
}, {
name: 'Bravo'
},{
name: 'Charlie'
},{
name: 'Delta'
}];
$scope.selected = $scope.items[0];
$scope.select = function (item) {
$scope.selected = item;
}
}
]);
Пример использования этой логики/данных в шаблоне дочернего состояния, sidebar.html:
<ul class="nav nav-pills nav-stacked">
<li ng-repeat="item in items" role="presentation">
<a href="#" ng-click="select(item)">{{item.name}}</a>
</li>
</ul>
Вот полный пример с вашими требованиями, я могу опубликовать весь код здесь, но я думаю, что это было бы слишком много:
http://embed.plnkr.co/2jKJtFM0GWsylyLcAdne/
Я с удовольствием отвечу на любой вопрос, который у вас есть, просто кричите. Удачи!
Ответ 3
если вы назовете контроллеры по-разному с контроллером, вы можете использовать NavCtrl в шаблоне sidebarCtrl. Может быть, использовать какое-то логическое значение, существующее в NavCtrl, которое решает, что показывать на боковой панели? (из комментария)
Это должно работать, но не пробовал.
.state('dash', {
url: '/dash/:id',
views: {
nav: {
controller: 'NavCtrl',
controllerAs: 'navCtrl',
templateUrl: '/views/navbar.html'
},
sidebar: {
controller: 'SidebarCtrl',
controllerAs: 'sidebarCtrl',
templateUrl: '/views/sidebar.html'
},
content: {
controller: 'DashCtrl',
controllerAs: 'dashCtrl',
templateUrl: '/views/dash.html'
}
}
})
sidebarService:
angular.module('app').value('sidebarService', {show: true});
navCtrl что-то вроде этого:
function(sidebarService){
var vm = this;
vm.toggleSideBar = function(){sidebarService.show = !sidebarService.show;}//used in navbar.html
}
sidebarCtrl:
function(sidebarService){
var vm = this;
vm.showSideBar= sidebarService;
}
а затем в sidebar.html вы используете службу бокового значения:
<div ng-if="sidebarCtrl.showSideBar.show">
<!--SideBar-->
</div
Ответ 4
Вы можете использовать события для связи между контроллерами. Проверьте документацию AngularJS для $scope.$broadcast
и `$ scope. $On: https://docs.angularjs.org/api/ng/type/ $rootScope.Scope