Coder Social home page Coder Social logo

artch / angular-route-segment Goto Github PK

View Code? Open in Web Editor NEW
454.0 27.0 100.0 743 KB

A lightweight extension for AngularJS $route service which supports tree-like nested views and routes, and advanced loading flow handling.

Home Page: http://angular-route-segment.com

JavaScript 92.89% CSS 0.41% HTML 6.70%

angular-route-segment's Introduction

angular-route-segment Build Status

A lightweight extension for AngularJS $route service which supports tree-like nested views and routes hierarchy, and advanced loading flow handling.

Getting Started

Example site is located here:

DEMO SITE

The sources of this example can be found in the folder /example.

You can install the library via Bower:

bower install angular-route-segment

Or using npm:

npm install angular-route-segment

Or using this CDN link (thanks to cdnjs.com):

<script src="//cdnjs.cloudflare.com/ajax/libs/angular-route-segment/1.5.0/angular-route-segment.min.js"></script>

Tested with AngularJS 1.2.21, 1.3.16, 1.4.9, 1.5.0.

Overview

This library is intended to provide the lacking functionality of nested routing to AngularJS applications. It is widely known, there are no ways to keep the parent state unchanged when children are updated via routing mechanics - the $route service re-creates the whole scope after a route is changed, losing its state completely. route-segment gives you a way to handle this.

The library provides two pieces of code: $routeSegment service and app-view-segment directive. Both are placed in their own modules which you must include as dependencies in your app module:

var app = angular.module('app', ['ngRoute', 'route-segment', 'view-segment']);

$routeSegment is a layer on top of built-in Angular $route service and is meant to be used instead of it. Its provider exposes configuration methods which can be used to traverse the tree of route segments and setup it properly.

app.config(function ($routeSegmentProvider) {

$routeSegmentProvider.

    when('/section1',          's1').
    when('/section1/prefs',    's1.prefs').
    when('/section1/:id',      's1.itemInfo').
    when('/section1/:id/edit', 's1.itemInfo.edit').
    when('/section2',          's2').

    segment('s1', {
        templateUrl: 'templates/section1.html',
        controller: MainCtrl}).

    within().

        segment('home', {
            default: true,
            templateUrl: 'templates/section1/home.html'}).

        segment('itemInfo', {
            templateUrl: 'templates/section1/item.html',
            controller: Section1ItemCtrl,
            dependencies: ['id']}).

        within().
	    
            segment('overview', {
                default: true
                templateUrl: 'templates/section1/item/overview.html'}).

            segment('edit', {
                 templateUrl: 'templates/section1/item/edit.html'}).

            up().

        segment('prefs', {
            templateUrl: 'templates/section1/prefs.html'}).

        up().

    segment('s2', {
        templateUrl: 'templates/section2.html',
        controller: MainCtrl});

Alternatively, you can use this syntax instead of traversing (useful if you want modules to have their own separately defined routes):

$routeSegmentProvider.segment('s1', {
    templateUrl: 'templates/section1.html',
    controller: MainCtrl});

$routeSegmentProvider.within('s1').segment('home', {
    templateUrl: 'templates/section1/home.html'});

$routeSegmentProvider.within('s1').segment('itemInfo', {
    templateUrl: 'templates/section1/item.html',
    controller: Section1ItemCtrl,
    dependencies: ['id']});
    
$routeSegmentProvider.within('s1').within('itemInfo').segment('overview', {
    templateUrl: 'templates/section1/item/overview.html'});

Then, any app-view-segment tags (which are similar to built-in ng-view) in the DOM will be populated with the corresponding route segment item. You must provide a segment index as an argument to this directive to make it aware about which segment level in the tree it should be linked to.

index.html:

<ul>
    <li ng-class="{active: $routeSegment.startsWith('s1')}">
        <a href="/section1">Section 1</a>
    </li>
    <li ng-class="{active: $routeSegment.startsWith('s2')}">
        <a href="/section2">Section 2</a>
    </li>
</ul>
<div id="contents" app-view-segment="0"></div>

section1.html: (it will be loaded to div#contents in index.html)

<h4>Section 1</h4>
Section 1 contents.
<div app-view-segment="1"></div>

...etc. You can reach any nesting level here. Every view will be handled independently, keeping the state of top-level views.

You can also use filters to define link hrefs. It will resolve segment URLs automatically:

<ul>
    <li ng-class="{active: ('s1' | routeSegmentStartsWith)}">
        <a href="{{ 's1' | routeSegmentUrl }}">Section 1</a>
    </li>
    <li ng-class="{active: ('s2' | routeSegmentStartsWith)}">
        <a href="{{ 's2' | routeSegmentUrl }}">Section 2</a>
    </li>
</ul>

Difference from UI-Router

While it seems that this library has very similar goal to what UI-Router provides, there are some important differences between their implementations, though.

UI-Router implements its own URL routing mechanics with its own "state" concept on top of it. angular-route-segment doesn't try to replace something in AngularJS. It is based on built-in $route engine, so that it tries to extend it rather than to replace. $routeSegmentProvider.when method is just a shorthand to $routeProvider.when with the simplified syntax. Inner segment-handling logic is built on top of events propagated by $route service, with internal usage of some route params from it.

Such approach makes it possible to accomplish the desired nested routing task in more simpler manner, which produces less code, less complexity and potential bugs, provides better cohesion with Angular core engine and is easier to understand, use and debug.

Documentation

Please note that you may read the test specs to learn features usage.

$routeSegmentProvider properties

options

A hash object which can be used to set up the service on config stage:

  • options.autoLoadTemplates

    When true, it will resolve templateUrl automatically via $http service and put its contents into template.

  • options.strictMode

    When true, all attempts to call within method on non-existing segments will throw an error (you would usually want this behavior in production). When false, it will transparently create new empty segment (can be useful in isolated tests).

when(path, name, route)

The shorthand for $routeProvider.when() method with specified fully qualified route name.

  • path

    Route URL, e.g. /foo/bar

  • name

    Fully qualified route name, e.g. foo.bar

  • route

    Mapping information object to be assigned to $route.current on route match.

segment(name, params)

Adds new segment at current pointer level.

  • name

    Name of a segment item, e.g. bar

  • params

    Segment's parameters hash. The following params are supported:

    • template provides HTML for the given segment view; if template is a function, it will be called with injectable arguments;
    • templateUrl is a template which should be fetched from the network via this URL; if templateUrl is a function, it will be called with injectable arguments; if neither template nor templateUrl parameters are defined, the DOM element's transcluded content will be used;
    • controller is attached to the given segment view when compiled and linked, this can be any controller definition AngularJS supports;
    • controllerAs is a controller alias name, if present the controller will be published to scope under the controllerAs name;
    • dependencies is an array of route param names which are forcing the view to recreate when changed;
    • watcher is a $watch-function for recreating the view when its returning value is changed;
    • resolve is a hash of functions or injectable names which should be resolved prior to instantiating the template and the controller;
    • untilResolved is the alternate set of params (e.g. template and controller) which should be used before resolving is completed;
    • resolveFailed is the alternate set of params which should be used if resolving failed;
    • default is a boolean value which can be set to true if this child segment should be loaded by default when no child is specified in the route.
within(childName)

Traverses into an existing segment, so that subsequent segment calls will add new segments as its descendants.

  • childName

    An existing segment's name. An optional argument. If undefined, then the last added segment is selected.

up()

Traverses up in the tree.

root()

Traverses to the root.

$routeSegment properties

name

Fully qualified name of current active route.

$routeParams

A copy of $routeParams in its state of the latest successful segment update. It may be not equal to $routeParams while some resolving is not completed yet. Should be used instead of original $routeParams in most cases.

chain

An array of segments splitted by each level separately. Each item contains the following properties:

  • name is the name of a segment;
  • params is the config params hash of a segment;
  • locals is a hash which contains resolve results if any;
  • reload is a function to reload a segment (restart resolving, reinstantiate a controller, etc)
startsWith(val)

Helper method for checking whether current route starts with the given string.

contains(val)

Helper method for checking whether current route contains the given string.

getSegmentUrl(segmentName, routeParams)

A method for reverse routing which can return the route URL for the specified segment name.

  • segmentName

    The name of a segment as defined in when().

  • routeParams

    Route params hash to be put into route URL template. Standard $routeParams object is used first; it is extended (overrided) with this provided object then.

$routeSegment.getSegmentUrl('s1');                              // -> '/section1'
$routeSegment.getSegmentUrl('s1.prefs');                        // -> '/section1/prefs'
$routeSegment.getSegmentUrl('s1.itemInfo', {id: 123});          // -> '/section1/123'
$routeSegment.getSegmentUrl('s1.itemInfo.edit', {id: 123});     // -> '/section1/123/edit'

Filters

ATTENTION: filters are not stateless. While they are not intended to work with complex data structures, it can impact performance anyway. See more info at angular.js commit fca6be71.

routeSegmentEqualsTo

A wrapper for $routeSegment.name == value.

<li ng-class="{active: ('s1' | routeSegmentEqualsTo)}">
routeSegmentStartsWith

A wrapper for $routeSegment.startsWith(value).

<li ng-class="{active: ('s1' | routeSegmentStartsWith)}">
routeSegmentContains

A wrapper for $routeSegment.contains(value).

<li ng-class="{active: ('s1' | routeSegmentContains)}">
routeSegmentParam

A wrapper for $routeSegment.$routeParams[value].

<li ng-class="{active: ('s1.itemInfo' | routeSegmentEqualsTo) && ('id' | routeSegmentParam) == 123}">
routeSegmentUrl

A wrapper for $routeSegment.getSegmentUrl.

<a ng-href="{{ 's1.home' | routeSegmentUrl }}">
<a ng-href="{{ 's1.itemInfo.edit' | routeSegmentUrl: {id: 123} }}">

License

The MIT License (MIT)

Copyright (c) 2013 Artem Chivchalov

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

angular-route-segment's People

Contributors

artch avatar jeffreypalmer avatar jincod avatar krmarien avatar paivaric avatar wingedfox avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

angular-route-segment's Issues

templateUrl doesn't work until options.autoLoadTemplates = true

Good day, @artch ! Thanks for your work!

It seems that templateUrl doesn't work if options.autoLoadTemplates is false.

Test Case:

  • Download this repo's demo.
  • It works.
  • Set options.autoLoadTemplates to false here.
  • It doesn't work (element marked by app-view-segment="0" is untouched).

What do you think? Thanks. P.S. Я русский.

Dynamic app-view-segment index

Hi there,

congrats for this incredibly useful plugin. I was wondering the following.
If I create the routes and the view segments dynamically without knowing the levels of the tree is it possible to make the app-view-segment index value dynamic?

Thanks a lot!

Reversing Routes

One of the things that always frustrated me about ngRoute was that I ended up hardcoding paths in my codebase. While this may be less typing initially, in the long run it leads to code that requires more work to maintain and integrate into other projects.

Coming from the Django world, where a Django project is made up of features modules, each describing their own url routes I became used to the concept of giving each route a shortname. Throughout my codebase (both project and the feature module) I would then build a url based on the short name and some parameters.

Fast forward to AngularJs, I created angular-named-routes. This works fine if you're only use ngRoutes, however I would like to utilise the nested view functionality of angular-route-segment.

Which leads me to my current situation: route-segment only exposes the first level of routes to ngRoute which means ngRoute has no idea what the path for a second level route might be.

I've created a gist with an attempt to illustrate the use case and some the start of a service that helps reverse a segment name into the full path:

https://gist.github.com/airtonix/9835196

Minified-версия

Приветствую!

Этот пакет предоставляется с minified-версией. Мало того, bower использует именно ее.

По соему опыту обычно подключается полная версия. Почему тут иначе? Спасибо.

Filter provider?

Hello!
Maybe a silly question but I can't find the filter you're providing. When I try to use them Im getting Error: [$injector:unpr] Unknown provider: routeSegmentEqualsToFilterProvider <- routeSegmentEqualsToFilter
In my app I have the dependencies: 'route-segment', 'view-segment' what else do I need to include?
Thanks!

Segment default params override actual ones

Segment definition

.segment('browse', {
     default: true,
     dependencies: ['what'],
     templateUrl: 'views/list.html',
     controller: 'FileListCtrl',
     params: {what: 'root'}

When I navigate directly to http://host/browse/home, I get the listing not from home, but from root instead.

Checked with release 1.3.0

Maintain route when switching top level navigation

Awesome control! The example website is a godsend for me. I do have one question... how would one go about maintaining the navigation on the individual sections (i.e.: the top level navigation)? For instance, if I am in section 1 and I navigate to one of items... Then go to section 2 and back to section 1... my section 1 navigation is reset again. Any recommendations for handling this?

Forcing router refresh

Already on SO: http://stackoverflow.com/questions/19812911/is-it-possible-to-refresh-route-segment-provider-in-angularjs

Basically, I'm using:

resolve: ['isUserLoggedIn'],
resolveFailed: {
templateUrl: 'assets/templates/login.html',
controller: LoginCtrl
}

to redirect to login page if user is not yet logged in.
The login controller redirects back to /#/index if user logged in successfully, but it seems that templateUrl and controller have already been decided and they don't get refreshed, isUserLoggedIn does not get called for the second time. Is this intended behaviour? Is there a way to forcefully refresh routing after initial setup?

routeSegmentChange problem

I'm have the follow structure:

$routeSegmentProvider
        .when('/login', 'login')    
        .when('/users', 'base.users')

        .segment('login', {
            templateUrl:  '/login/login.html',
            controller: 'LoginCtrl', 
            permissions : {
                login: false,
                profiles: [profiles.public]
            }
        })

        // Use this for not reload the UI
        .segment('base', {
            templateUrl:  '/base.tpl.html',
            controller: 'UIBaseCtrl',
            permissions : {
                login: true,
                profiles: [profiles.common]
            }
        })

        .within()
            .segment('users', {
                default: true,
                templateUrl:  '/users/users.tpl.html',
                controller: 'UsersCtrl', 
                permissions : {
                    login: true,
                    profiles: [profiles.admin]
                }
            })

In my app.run:

$rootScope.$on("routeSegmentChange", function(event, route) {
            console.log(route);

In tests, I found a error in this follow situation:

  1. /login: route, at index 0 => OK
  2. /users: route => OK
    • go to segment ui, at index 0
    • go to segment ui.users, at index 1
  3. /login: when I return to /login, are showed 3 route objects

First: an route Obj, at index 0, as name login.
Second: an route Obj, at index 1, segment = null
Third: an route Obj, at index 1, segment = null

The second and third should not appear. This causes an error when trying to check the permissions to try to authenticate the route.

For example, if I use:

console.log(route.segment.name);

The console returns:

  1. login
  2. ui
  3. users
    and when back to /login, console show:
  4. login
  5. TypeError: Cannot read property 'name' of null
  6. TypeError: Cannot read property 'name' of null

In one more example, if I use:

console.log($routeSegment);

for same sequence of routes calls, the console show the objects:

  1. Object {name: "login", $routeParams: Object, chain: Array[1] ...
  2. Object {name: "ui", $routeParams: Object, chain: Array[1] ...
  3. Object {name: "ui.users", $routeParams: Object, chain: Array[2] ...
  4. Object {name: " login.users ", $routeParams: Object, chain: Array[1]
  5. Object {name: "login", $routeParams: Object, chain: Array[2] ...
  6. Object {name: "login", $routeParams: Object, chain: Array[1] ...

In this case 4 seems to be an error because login.users segment does not exist.

Someone could give a help?

** I tested when $routeChangeStart, but the $routeSegment is always the previous. **.

app-view-segment should clean itself up when a route has a normal controller instead of a segment

I would like to be able to mix classical angular views with app-view-segment views; however, when I transition from a segment view to a normal view, the segment view remains.

Setup is as follows:

$routeSegmentProvider
    .when('/segment', 's1.home')
    .segment('s1', {
        template: 's1:<div app-view-segment="1"></div>'
    })
    .within().segment('home', {template: 'home'});
$routeProvider
    .when('/', { template: 'no segment'})

index.html contains:

<div app-view-segment="0"></div>
<div ng-view=""></div>

Plunkr - click "to segment" and then "to root"; the segment view remains.

ng-view cleans up after itself if there is no template (and even removes the element via transclusion); app-view-segment should do the same thing.

This is my current workaround:

app.run(function($rootScope, $routeSegment) {
    $rootScope.$on('$routeChangeSuccess', function(event, current, previous) {
        var segmentsOn = false, segmentsOff = false, inPrev = false, inCurrent = false;
        if (previous != null) {
            inPrev = 'segment' in previous;
            inCurrent = 'segment' in current;
        }
        segmentsOff = inPrev && !inCurrent;
        segmentsOn = inCurrent && !inPrev;
        if (segmentsOff || segmentsOn) {
            $rootScope.$broadcast('routeSegmentChange', {
                index: 0, segment: segmentsOff ? null : $routeSegment.chain[0]
            });
        }
    });
});

reverse routes

Hi,
It would be very nice if you add some reverse functions.
I created something similar in my last project. And it looks like this one.

  1. resolve - service, which have 2 methods. href and hash.

    > resolve.href( "route.name", [arg1, arg2] ) 
    /route/name/arg1/arg2/
    > resolve.hash( "route.name", [arg1, arg2] ) 
    #!/route/name/arg1/arg2/
    
  2. url - filter.

    {{ "route.name" | ulr: [arg1, arg2] }}
    returns resolve.hash( "route.name", [arg1, arg2] )
    
  3. redirectTo service

    redirectTo( "route.name", [arg1, arg2] )
    returns $location.path(resolve.href( "route.name", [arg1, arg2] ))
    

make sense?

Watcher not being cleared.

Good day Artem.
First, thank you for a great component - using it is generally pleasant.

Second, I've encountered the following issue - if you have a segment with watcher function,
like this

.segment('Operators', {
                templateUrl: 'MyView',
                controller: 'MyCtrl',
                watcher: function () {
                      return window.location.hash;
                  }
            })

the watcher doesn't get properly cleaned. This happens under specific conditions, for example, if you go from Group.Operators => Group, i.e. the new chain has less segments and the segment with the watcher was among the segments that should be cleaned.
This causes the watcher to continue existing and trying to call reload on a nonexisting chain segment.

Here is a small app that illustrates this problem https://dl.dropboxusercontent.com/u/9307640/wacher-problem.zip

I've traced it to the following part of code:
route-segment.js

260    if($routeSegment.chain[j]) {
261             $routeSegment.chain[j] = null;
262              updateSegment(j, null);
263         }
...
327        function updateSegment(index, segment) {
328
329            if($routeSegment.chain[index] && $routeSegment.chain[index].clearWatcher) {
330                $routeSegment.chain[index].clearWatcher();
331            }

updateSegment should clean the watcher, but by the time it executes

$routeSegment.chain[j] = null; 

has already removed the reference to that chain segment and the watch is leaked.

Looking forward to a fix.

Segment defaults do not pass to the segment controller and below

When I navigate to the root segment with default sub-segment and pre-defined parameters I get

Error: Route param `what` is not specified for route `/browse/:what`

Segment:

.segment('browse', {
     default: true,
     dependencies: ['what'],
     templateUrl: 'views/list.html',
     controller: 'FileListCtrl',
     params: {what: 'root'}

Controller

.controller('FileListCtrl', [
    '$scope', '$routeSegment',
    function ($scope, $routeSegment) {
       $routeSegment.$routeParams.what; // undefined

Target url: http://host/browse

Yeah, I'll add a demo, but not right now. Anyway, the bug exists and it is easy reproducible.

TypeError: Cannot read property 'name' of null

Hello!
Thank you for this great extension!
I just cloned this repo and launched the example and Im getting this error on Chrome only (Error is not happening on your hosted example)

TypeError: Cannot read property 'name' of null
    at Object.q.contains (http://0.0.0.0:9001/build/angular-route-segment.min.js:7:2870)
    at Object.value (http://ajax.googleapis.com/ajax/libs/angularjs/1.2.0rc1/angular.js:8522:19)
    at extend.literal (http://ajax.googleapis.com/ajax/libs/angularjs/1.2.0rc1/angular.js:8573:41)
    at Object.Scope.$eval (http://ajax.googleapis.com/ajax/libs/angularjs/1.2.0rc1/angular.js:9953:28)
    at http://ajax.googleapis.com/ajax/libs/angularjs/1.2.0rc1/angular.js:14799:36
    at http://ajax.googleapis.com/ajax/libs/angularjs/1.2.0rc1/angular.js:4464:13
    at Object.Scope.$eval (http://ajax.googleapis.com/ajax/libs/angularjs/1.2.0rc1/angular.js:9953:28)
    at Object.Scope.$digest (http://ajax.googleapis.com/ajax/libs/angularjs/1.2.0rc1/angular.js:9809:23)
    at Object.Scope.$apply (http://ajax.googleapis.com/ajax/libs/angularjs/1.2.0rc1/angular.js:10039:24)
    at HTMLHtmlElement.<anonymous> (http://ajax.googleapis.com/ajax/libs/angularjs/1.2.0rc1/angular.js:7613:22) angular.js:7818

Not sure what it is and how can I solve this

Access route params in resolve function

The $routeParams don't seem to be populated when the resolve step is being performed. So, inside my resolve function, I can't access these route params. It seems to me the natural use case for the resolve function would be using the route params to resolve/load something? Am I thinking about this wrong?

My scenario: I have a page with an ID in the URL, I want to grab a resource off the server based on that ID before loading the page. So I'm doing this:

$routeSegmentProvider.when('/accept-invite/:token', 'accept-invite')
        .segment('accept-invite', {
            templateUrl: 'partials/signin/accept-invite.tpl.html',
            controller: 'AcceptInviteCtrl',
            resolve: {
                invite: function(Auth, $routeSegment) {
                    return Auth.getInvite($routeSegment.$routeParams.token);
                }
            }
        });

Auth.getInvite() returns an $http.post() promise.

How set custom params?

I've got a code which works perfectly

$routeProvider.when('/',{
        access: access.user
        ,someKey:{ss:"dd"}
    });

and when I need a check

app.run(['$rootScope', '$location', 'Auth', '$log' function ($rootScope, $location, Auth, $log ) {
    $rootScope.$on("$routeChangeStart", function (event, next, current) {
        if (!Auth.authorize(next.access)) {    //<<<--whith segment here occures an Error

            if(Auth.isLoggedIn()) {

            } else {

            }
        } else {

        } 
    });
}]);

all works well.
I mean, that there is "next.access" exists which a set above.

But, with segments its not works if

$routeSegmentProvider
        .when('/', 'mainRoot')
        .segment('mainRoot',{
            controller: 'mainRootCtrl'
            ,access: access.user
        })

How Can I solve this problem?

Custom options in segments

I was using custom options with ng-route, that were really useful, because I can provide settings based on the route.

Tried something like that with angular-route-segment but didn't worked.

Something like this would be awesome:

segment('dashboard', {
    templateUrl: loc + 'templates/dashboard.html',
    controller: 'DashboardCtrl',
    requireLogin: true,
    hasSidebar: true
}).

Or do you recommend a better way to do this?

Resolves behave differently from ngRoute

Example: http://plnkr.co/edit/5tqVwC

Question 1:

The example showed how redirection in resolve function will affect template and controller. When using route-segment, redirection in before resolve resolved is temporary. Once the resolve finish, original controller and template (OneCtrl and template-one) will be loaded back into <div app-view-segment></div> and keeping url with #/three.

On the other hand, ngRoute will not load OneCtrl and its template back into ng-view after redirection.

Question 2:

The example did not illustrate this problem.

But if I'm using a service name as resolve, the service function will be executed every time I route to that address. Not like in ngRoute, only function resolver will be executed every time, service resolver will only be executed once, which is the right behavior of a service.

Question 3:

Will this module support the new controllerAs syntax?


I really love this nested view module, especially the untilResolve option. Thank you in advance.

Example site breaks with angular-route 1.3.0

I had to revert to version 1.2.21 of angular-route because the example site gave the following error when run locally against 1.3.0:

Error: [ng:areq] Argument 'MainCtrl' is not a function, got undefined
http://errors.angularjs.org/1.3.0-build.2959+sha.aa7dbf0/ng/areq?p0=MainCtrl&p1=not%20a%20function%2C%20got%20undefined
    at http://localhost:54328/bower_components/angular/angular.js:78:12
    at assertArg (http://localhost:54328/bower_components/angular/angular.js:1570:11)
    at assertArgFn (http://localhost:54328/bower_components/angular/angular.js:1580:3)
    at http://localhost:54328/bower_components/angular/angular.js:7448:9
    at http://localhost:54328/bower_components/angular/angular.js:6791:34
    at forEach (http://localhost:54328/bower_components/angular/angular.js:334:20)
    at nodeLinkFn (http://localhost:54328/bower_components/angular/angular.js:6778:11)
    at compositeLinkFn (http://localhost:54328/bower_components/angular/angular.js:6216:13)
    at compositeLinkFn (http://localhost:54328/bower_components/angular/angular.js:6219:13)
    at compositeLinkFn (http://localhost:54328/bower_components/angular/angular.js:6219:13)

change from function controller to module controller problem

Hi,
I'm fairly new to this lib, and in app.js I was trying to change from:

function MainCtrl($scope, $routeSegment, loader) {
$scope.$routeSegment = $routeSegment;
$scope.loader = loader;
$scope.$on('routeSegmentChange', function() {
loader.show = false;
})
}

to:

app.controller('MainCtrl', ['$scope', '$routeSegment', 'loader', function($scope, $routeSegment, loader) {
$scope.$routeSegment = $routeSegment;
$scope.loader = loader;
$scope.$on('routeSegmentChange', function() {
loader.show = false;
})
}]);

however, it doesn't seems working, can you help me look at the code and tell me where I did wrong? I've been googling and looking at documentations but no luck...
Thanks!

how to force re-render?

i need to re-render a section depending on the result of a method.. for ex:

if (refreshDashboard() == true)
{
$scope.$routeSegment.reload();
}

can it be done? thanks!

State not being preserved

On the demo site it says that you can navigate through sections without them losing state. I've tried it out and but when I change sections (e.g. from Section 1 to Section 2 and back to Section 1) all state is lost.

Any ideas?

The directive link function be called twice

When I'm using angular-route-segment, I have this route settings:

$routeSegmentProvider
.when('/item/:id', 'item.edit')

$routeSegmentProvider.segment('item', {
templateUrl: '/html/item.html',
controller: 'item',
dependencies: ['id']
});
$routeSegmentProvider.within('item').segment('edit', {
templateUrl: '/html/edit.html',
controller: 'edit'
});

Then I have a directive like this:
var myDirective = function() {
return function(scope, element, attrs, controller) {
console.log('myDirective');
};
};

this directive be called in edit.html

Then I found the directive function be called twice.

Is there any way to fix it? It's cause a problem when I add some event listener on element in the directive. If it's be call twice, means the event handler be added twice.

Should list angular-route as dependency in bower.json

Since angular-route is a dependency this should be listed explicitly in bower.json. Took me a while to figure out why it wasn't working & expecting new users to figure this out for themselves is definitely not user-friendly.

search (part of url) watching

Good day!

It seems that nothing happens when I change location from #/ to #/?favorite=1.
Can I tell angular-route-segment to watch this and to reload the route?

Thanks.

Custom parameters inside segment

In $routeProvider, I would have custom paramters that would define the route access level:

$routeProvider.when({
  templateUrl: 'templateUrl.html',
  controller: 'MyController',
  access_level: ROUTE_ACCESS_LEVELS.ONLY_LOGGED_IN
})

I see in the test spec that you are adding in a custom hash - { test: 'A' }. How would I get the value of custom parameters in a $rootScope onChangeStart event?

Before I was doing

.run(['$rootScope', 'ROUTE_ACCESS_LEVELS', 'userService', function($rootScope, ROUTE_ACCESS_LEVELS)  {
  $rootScope.$on('$routeChangeStart',   function(evt, next, curr) {
    console.log(next.access_level)
    // do stuff with access_level

I can't seem to find the access_level parameter inside evt, next, or curr. Are custom parameters available in angular route segment?

Problems understanding the usage!

Hi,

I'm fairly new to AngularJS and I am having problems using your library. Here is my code…

app.config(function ($routeSegmentProvider, $routeProvider){

$routeSegmentProvider.options.autoLoadTemplates = true;

$routeSegmentProvider.
    when('/login', 'login');

$routeSegmentProvider.segment('login', {
        templateUrl: 'partials/login.html',
        controller: 'LoginController'
    });
    $routeProvider.otherwise({redirectTo: '/login'});
});

Here's my login.html

<div>
  <form>
  <a href="#">Login with Facebook</a>
  <br/>
  <label>Email:</label>
  <input type="text" ng-model="user.email" placeholder="email" required>
  <br/>
  <label>Password:</label>
  <input type="password" ng-model="user.password" placeholder="password" required>
  <br/>
  <button ng-click="login()"/>Log In!</button>

  <br/>
  <a href="#/signup">Sign Up using Email</a>
</form>
</div>

And I also have a LoginController defined -

app.controller('LoginController', function($scope, $location, UserService) {
//more code in here…
});

This is my index.html

<body>
<div id="contents" app-view-segment="0"></div>
</body>

When I navigate to appName/#/login I don't see anything, but the code in LoginController is getting executed. I can't understand what I'm doing wrong here. Could you please explain?

Change location before template is fired

Good day, @artch !

I want to change location before template is fired.

So I get authorization status via resolve via $http and do $location.path('/login') in controller. But template is fired before location changed instead.

Can you help me please?

Reversing routes needs to consider `hashPrefix` and `html5Mode`

related to #38 and #34
For references, I present an implementation of a simpler named routes module I've created before discovering angular-route-segment

Key points:

Apparently in newer versions of angular the hash prefix is implied when html5mode is false

Looks really promising!

I'm using ui-router for few of my projects. angular-route-segment looks something similar. I like the syntaxes! Can you please let us know comparision between this and ui-router?

Great work, Thanks!

<div app-view-segment="1"></div> does not work inside ng-if

Good day again, Artem.

We have a nested route where we only want to load segments after the first if the first one successfully loaded data. We are using resolve:{...} in the route and in the template of first segment:

<div ng-if="group"> 
     <div app-view-segment="1"></div>
</div>

It doesn't work - the element gets added to the DOM, but the segment doesn't show up inside it.

We found a workaround like this

    <script type="text/ng-template" id="app-view-segment1.html">
         <div app-view-segment="1"></div>
    </script>

   <div ng-if="group"> 
        <div class="span10 early-full-width">
              <div ng-include=" 'app-view-segment1.html' "></div>
       </div>
    </div>

but since this looks like a bug - maybe a permanent fix is in order.

TypeError: Cannot read property 'property' of undefined

I get TypeError: Cannot read property 'productbacklog' of undefined when routes are defined separately in 2 modules, projects and productbacklog:

angular.module('projects', ['productbacklog'])

.config(['$routeSegmentProvider', function ($routeSegmentProvider) {
    $routeSegmentProvider.when('/projects', 'projects');
    $routeSegmentProvider.segment('projects', {
        templateUrl:'projects/projects-list.tpl.html'
    });
}]);

angular.module('productbacklog', [])
.config(['$routeSegmentProvider', function($routeSegmentProvider){
$routeSegmentProvider.when('/projects/:projectId/productbacklog', 'projects.productbacklog.list');
$routeSegmentProvider.within('projects').within('productbacklog').segment('list', {
templateUrl: "projects/productbacklog/productbacklog-list.tpl.html"
});
}]);

But if I define both routes in projects module then it work:

angular.module('projects', ['productbacklog'])

.config(['$routeSegmentProvider', function ($routeSegmentProvider) {
    $routeSegmentProvider.when('/projects', 'projects');
    $routeSegmentProvider.segment('projects', {
        templateUrl:'projects/projects-list.tpl.html'
    });

    $routeSegmentProvider.when('/projects/:projectId/productbacklog', 'projects.productbacklog.list');
    $routeSegmentProvider.within('projects').within('productbacklog').segment('list', {
        templateUrl: "projects/productbacklog/productbacklog-list.tpl.html"
    });
}]);

Controller invoked more then one times

Hi! Thank you for grate library! But I have a troble.
When we have some segments tree, let's say 's1.infoItem.Z', and controllers attached to every of subsegment, controller of last segment invoked triple times if we open page on '/segment1/2/Z' (not navigate to it from home!). I think it's a bug.
I spend a couple of hours to find the solution and i think i found it. Just comment this two lines in appViewSegment directive:

if ($routeSegment.chain[viewSegmentIndex])
     update($routeSegment.chain[viewSegmentIndex]);

After some tests i suggest that all works fine. Please, explain meaning of this two lines and why after commenting all just works?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.