2015-10-05 14 views
7

In unserer Angular App müssen wir mit IDs, die einen "Punkt" enthalten beschäftigen. Zum Beispiel:Angular Ui-Router mit URL-Abfrage-Parameter mit einem "Punkt"

book = { 
    id: '123.456' 
} 

Wir haben Probleme mit solchen IDs als URL-Parameter. Alles funktioniert gut, wenn die Navigation durch "Angular" erfolgt, nämlich durch Klicken auf den Link, der $state.go('bookDetails', {bookId: book.id}); aufruft. Aber die Dinge funktionieren nicht, wenn die Seite neu zu laden

"Can not Get /bookDetails?bookId=123.456"

in der Steuerung:

$scope.viewBookDetails = function() { 
    $state.go('bookDetails', {bookId: book.id}); 
} 

in der Ansicht

<a href="" ng-click="viewBookDetails(); $event.stopPropagation();"> 

in der Router:

.state('bookDetails', { 
    url: '/bookDetails?bookId' 
} 

im Browser:

https://example.com/bookDetails?bookId=123.456 

Der Link funktioniert, wenn der "Punkt" mit %2E im Browser ersetzt.

$scope.viewBookDetails = function() { 
    $state.go('bookDetails', {bookId: book.id.split('.').join('%2E')}); 
} 

Wir haben versucht, "Punkt" mit "% 2E" in dem Parameter für state.go() $ zu ersetzen, aber nicht funktioniert, weil die "%" automatisch codiert und die "dot" im Browser wird durch "% 252E" ersetzt

https://example.com/bookDetails?bookId=123%252E456 
+0

Vielleicht sluggify für diesen Einsatz: https://github.com/paulsmith/angular-slugify ich bin nicht sicher, ob es in Ihrem Fall funktioniert. – Michelangelo

Antwort

5

Das Refresh-Problem, das ich mit einem URL-Abfrageparameter immer einen 'Punkt' enthält, ist ein Server-Problem.
Es wird durch die Art und Weise verursacht ich mit html5mode umgehen (umleiten, wenn auf index.html keine statische Ressource ist) in den Grunzen-Server-Einstellungen

// The original grunt server settings 
connect: { 
    options: { 
    port: 9000, 
    // Change this to '0.0.0.0' to access the server from outside. 
    hostname: 'localhost', 
    livereload: 35729 
    }, 
    livereload: { 
    options: { 
     open: true, 
     middleware: function (connect) { 
     return [ 
      require('connect-modrewrite')(['^[^\\.]*$ /index.html [L]']), //Matches everything that does not contain a '.' (period) and causes the problem 
      connect.static('.tmp'), 
      connect().use(
      '/bower_components', 
      connect.static('./bower_components') 
     ), 
      connect().use(
      '/app/styles', 
      connect.static('./app/styles') 
     ), 
      connect.static(appConfig.app) 
     ]; 
     } 
    } 
    }, 

Ich änderte

require('connect-modrewrite')(['^[^\\.]*$ /index.html [L]']), 

zu

require('connect-modrewrite')([ 
    '!\\.html|\\.js|\\.css|\\.svg|\\.jp(e?)g|\\.png|\\.gif|\\.ttf$ /index.html' 
]), 
1

Ich habe den Code komplett überarbeitet. Ich kann Punkte gut gebrauchen, also bitte den Plunker auspeilen, um zu zeigen, wo du einen Fehler bekommst.

http://plnkr.co/edit/Ct09Q9uoc282JuWdsO1s?p=preview

console.log("Scripts loading... "); 
 

 
// Here's a skeleton app. Fork this plunk, or create your own from scratch. 
 
var app = angular.module('demonstrateissue', ['ui.router']); 
 

 
app.controller('myController', function($scope, $state){ 
 
    $scope.book = { 
 
    id: '123.456' 
 
}; 
 
    
 
    $scope.viewBookDetails = function() { 
 
    console.log('new id'); 
 
    $state.go('bookDetails', {bookId: 456.3456}); 
 
    } 
 
}); 
 

 

 

 
// Empty config block. Define your example states here. 
 
app.config(function($stateProvider, $urlRouterProvider, $urlMatcherFactoryProvider) { 
 
    $stateProvider.state('bookDetails', { 
 
    url: '/bookDetails:bookId', 
 
    controller: function($scope, $stateParams) { 
 
     $scope.book = { 
 
     id: $stateParams.bookId 
 
     }; 
 
    }, 
 
    template: "<h3>book: {{book}}</h3>" 
 
    }); 
 

 
    $urlRouterProvider.otherwise("/bookDetails/91.23"); 
 
}); 
 

 
// Adds state change hooks; logs to console. 
 
app.run(function($rootScope, $state, $location) { 
 
    
 
    $rootScope.$state = $state; 
 
    $rootScope.$location = $location; 
 
    
 
    function message(to, toP, from, fromP) { 
 
    return from.name + angular.toJson(fromP) + " -> " + to.name + angular.toJson(toP); 
 
    } 
 
    
 
    $rootScope.$on("$stateChangeStart", function(evt, to, toP, from, fromP)  { console.log("Start: " + message(to, toP, from, fromP)); }); 
 
    $rootScope.$on("$stateChangeSuccess", function(evt, to, toP, from, fromP)  { console.log("Success: " + message(to, toP, from, fromP)); }); 
 
    $rootScope.$on("$stateChangeError", function(evt, to, toP, from, fromP, err) { console.log("Error: " + message(to, toP, from, fromP), err); }); 
 
});
body { 
 
    margin-top: 6em; 
 
} 
 
.link { 
 
    text-decoration: underline; 
 
    color: blue; 
 
} 
 

 
.link:hover { 
 
    cursor: pointer; 
 
} 
 

 
.header { 
 
    position: fixed; 
 
    right: 0; 
 
    top: 0; 
 
    height: 6em; 
 
    width: 100%; 
 
    border-bottom: 1px solid gray; 
 
}
<!DOCTYPE html> 
 
<html> 
 
    <head> 
 
    <script src="https://code.angularjs.org/1.2.25/angular.js"></script> 
 
    <script src="https://rawgit.com/angular-ui/ui-router/0.2.13/release/angular-ui-router.js"></script> 
 
    <script src="main.js"></script> 
 
    <link rel="stylesheet" href="styles.css" /> 
 
    <title>Plunk demonstrating ui-router issue</title> 
 
    </head> 
 

 
    <body ng-app="demonstrateissue"> 
 

 
     <div ui-view>ui-view not populated</div> 
 
    
 
     <div class="header"> 
 
     Current URL: <b>{{$location.url() }}</b> <br> 
 
     Current State: <b>{{$state.current.name }}</b> <br> 
 
     Current Params: <b>{{$state.params | json }}</b><br> 
 
     </div> 
 
    <br/> 
 
    <br/> 
 
    <div ng-controller="myController"> 
 
     {{book}} 
 
     <br/> 
 
     <a ui-sref="bookDetails({bookId: 6789.1011})">Change params to book with dot</a><br/> 
 
     <button ng-click="viewBookDetails()">View Book Details</button> 
 
     </div> 
 
    </body> 
 
</html>

+0

Wie würden Sie das in $ stateProvider.state() verwenden? – klode

+0

Ich habe den Code aktualisiert bitte überprüfen Sie und lassen Sie mich wissen, wo Ihr Fehler. – Enkode

+0

Wie ich bereits sagte, das Problem ist nicht in den Zustand gehen, aber wenn ** die bookDetails Seite ** neu laden (Browser aktualisieren, wenn auf den BuchDetails). – klode

2

Wenn Sie connect-history-api-fallback auf Ihrem Server verwenden (wie lite-server), werden die URLs mit einem Punkt standardmäßig nicht neu geschrieben.

connect-history-api-fallback code

if (parsedUrl.pathname.indexOf('.') !== -1) { 
    logger(
    'Not rewriting', 
    req.method, 
    req.url, 
    'because the path includes a dot (.) character.' 
); 
    return next(); 
} 

Beginnend mit connect-history-api-fallback Version 1.2.0 die URLs with dots are allowed und Sie können this problem lösen, indem aa mit rewrite roule

Beispiel

Wenn Ihre URL mit Punkt ist /api/test/:id (ex. /api/test/123.34) und Sie Winkel App Leben in der index.html Seite können Sie eine Rewrite hinzufügen Regel an den connect-history-api-Rückfall wie diese

rewrites: [ 
    { 
    from: /^\/api\/test\/[0-9]+\.[0-9]+$/, 
    to: 'index.html' 
    } 
    } 
] 
Verwandte Themen