Switching views within the same controller whilst

2019-08-12 00:52发布

问题:

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?

回答1:

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.



回答2:

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