简体   繁体   中英

Angular.js - Two Concurrent But Exclusive Routes ($routeProvider)

<div id="header">
    Header
</div>
<div id="wrapper">
    <div id="slider" ng-view>
        Slider
    </div>
    <div id="mainWindow" ng-view>
        Main window
    </div>
</div>

http://jsfiddle.net/abehnaz/k9Y4f/

I am working with a webapp that has two major views. The first is a main window (standard stuff), and the second is a "slider". The slider is more than a slide out menu (sometimes called a "shelf"). It has routing and secondary information associated with it.

In what seems to be the normal Angular paradigm, I would use a single ng-view in the main window, and that would populate the main window with the results of the $routeProvider's view template.

However, here I want to be able to ALSO have the slider have its own route. Angular does not seem to support this. I was thinking that I could potentially hack the functionality in by making a client side URL of the form:

www.app.com/MAINWINDOW/someView1/someView2/SLIDER/someViewa

Am I on the right track with this, or is there another functionality of Angular that I can use?

I would not recommend two routeParameters. Make your sidebar a service and put a controller on your wrapper, slider, and mainWindow. By having the ng-controller on #wrapper as well as the children, you can share data between the controllers (and in turn, inject the service into those controllers. I have done this and it was very successful. See an example below. In my code, my ng-view and routing returned everything within the <div ng-app="myApp"> . You could easily put the ng-view in the MainCtrl and trigger routes from the sidebar.

In your template:

<div ng-app="myApp">
  <div ng-view>
    //Produced by routing
    <div id="wrapper" ng-controller="RootCtrl">
        <div id="Sidebar" ng-controller="SidebarCtrl">
            ...
            <div ng-click="setUnit(mod.number, unit.number)">Unit 1</div>
            ...
        </div>
        <div id="mainWindow" ng-controller="MainCtrl">

        </div>
    </div>
  </div>
</div>

In your javascript:

A service:

myApp.service('questionsSvc', function(Modules) {
    var QuestionsSrc = {};
    QuestionsSrc.questions = [];
    var getQuestionsForModAndUnitFn = function(mod, unit) {
         ...bunch of code to have it populate QuestionSrc with questions
    };
    return {
        getQuestionsForModAndUnit: getQuestionsForModAndUnitFn,
        Questions: QuestionsSrc
    };
});

For Controllers:

function RootCtrl($scope) {
    $scope.data = {};
}

function SidebarCtrl($scope, Modules, questionsSvc) {

    $scope.setUnit = function (mod, unit) {
        questionsSvc.getQuestionsForModAndUnit(mod, unit);
        $scope.data.questions = questionsSvc.Questions.questions;
        //$scope.data.questions was used in the MainCtrl window to do an ng-repeat on the json array of questions bound to this model.
    }
};

function MainCtrl($scope){
    ...whatever you need to manipulate the code...
}

With this example, I am sharing information across Controllers. The magic is with the $scope.data = {}; from the RootCtrl. It allows me to attach questions to the $scope based on an action in the Sidebar (clicking a label) and use that same $scope in the MainCtrl to display the questions in a pretty format. With what I just showed, I did not have to use $routeParameters to pass variables to go to another page (such as module and quiz) but I could have done so as you asked but would have had the sidebar ng-click change routes.

Hope this helps.

One solution is to use Angular UI router :

AngularUI Router is a routing framework for AngularJS, which allows you to organize the parts of your interface into a state machine. Unlike the $route service in Angular core, which is organized around URL routes, UI-Router is organized around states, which may optionally have routes, as well as other behavior, attached.

States are bound to named, nested and parallel views, allowing you to powerfully manage your application's interface.

Just to give a flavor for how you could use AngularUI Router- It supports multiple named views (which you can read more about under "Multiple & Named Views" in their docs). So for instance you can use ui-view with names:

<div id="wrapper">
    <div id="slider" ui-view="slider">
        Slider
    </div>
    <div id="mainWindow" ui-view="main">
        Main window
    </div>
</div>

Then within config you can attach states to various routes and specify what each view should display for that state.

myapp.config(function($stateProvider, $urlRouterProvider){
  $stateProvider
    .state('index', {
        url: "/index",
        views: {
            "Slider": {
                templateUrl:"route1.viewA.html"
            },
            "Main": {
                templateUrl:"main1.viewA.html"
            }
        }
    })
    .state('slider2', {
        url: "/slider2",
        views: {
            "Slider": {
                templateUrl:"route2.viewA.html"
            },
            "Main": {
                templateUrl:"main1.viewA.html"
            }
        }
    })

There's a variety of other ways you could use AngularUI Router though. For instance, you may be able to get away with just using nested routes- which they recommend trying first.

Here's a couple more good reference material you might check out:

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM