I have a page of data that can be viewed as a list or as markers on a map. It also has filtering in the sidebar. I currently have this structured as separate map and list pages but I want to merge them so that the filters remain when switching views.
I have tried using ui-router
but due to my markup I cannot keep the filtering within a parent state, as per my question here: How do I show multiple views in an abstract state template?
My current markup is like this:
<div class="main-container" ng-controller="PlanningCtrl" data-county-parish-id="1478">
<main class="page-content">
<!-- toggles between map and list views -->
<a href="/map">View map</a>
<!-- main content view here -->
<appl-list></appl-list>
<!-- <appl-map></appl-map> -->
</main>
<aside class="sidebar">
<div refine-results info="refine" id="SearchForm" class="refine-search"></div>
</aside>
</div>
The data array is within the controller as $scope.filteredApplications
and on each page this is filtering and displaying fine within each directive.
I guess my question is: how can I toggle between the two <appl-*>
directives and display the same filtered records?
You can use ng-if with your directives and set value based on a scope variable.
Your controller would have something like:
$scope.show = 'List'
Then you'd have this in your HTML:
<appl-list ng-if="show==='List'></appl-list>
<appl-map ng-if="show==='Map'></appl-map>
Then you'd toggle the value of $scope.show between 'List' and 'Map' based on some event.
If I understand your issue correctly, solution is really very close. We will profit from UI-Router native design. Here is a full story (with working example):
How do I share $scope data between states in angularjs ui-router?
So, what we should do, is to properly use view data inheritance - which works well with some reference property, e.g. Model : {}
declared on the parent state (root view)
controller('rootController', function ($scope) {
$scope.Model = {SomeProperty : "xxx"}; // root controller creates it
})
We can (could) also introduce the some super root state, and easily inject that into each state family super parent
.state('root', {
template: "<div ui-view></div>",
controller: "rootController"
}
// any grand parent of some state hierarchy
.state("business", {
parent: "root",
...
.state("athorization", {
parent: "root"
and later any controller (any because, we inherit from root unnamed view) can do filtering
$scope.Model.Filter = {...}
And any other controller can use that filter
$scope.filterPlanning = function() {
var data = ...
var filter = $scope.Model.Filter;
// filter magic
...
return filteredOutput;
}
Similar technique, including examples in TypeScript could be found here (also has working example)
Angular Digest cycle being ran but ng-bind value not updating