2015-10-05 15 views
7

Trong ứng dụng Góc của chúng tôi, chúng tôi phải xử lý id có chứa "dấu chấm". Ví dụ:Angular ui-router với tham số truy vấn url chứa "dấu chấm"

book = { 
    id: '123.456' 
} 

Chúng tôi gặp sự cố khi sử dụng id như thông số url. Tất cả hoạt động tốt nếu điều hướng xảy ra thông qua "Góc", cụ thể là nhấp vào liên kết gọi số $state.go('bookDetails', {bookId: book.id});. Nhưng mọi thứ không làm việc khi tải lại trang

"Không thể GET /bookDetails?bookId=123.456"

trong bộ điều khiển:

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

trong giao diện

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

trong bộ định tuyến:

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

trong trình duyệt:

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

Liên kết hoạt động nếu "dấu chấm" được thay thế bằng %2E trong trình duyệt.

Chúng tôi đã cố gắng để thay thế "chấm" với "% 2E" trong tham số với $ state.go()

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

nhưng không làm việc vì "%" được tự động mã hóa và "chấm" trong trình duyệt được thay thế bằng "% 252E"

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

có lẽ sử dụng sluggify cho việc này: https://github.com/paulsmith/angular-slugify tôi không chắc chắn nếu nó hoạt động trong trường hợp của bạn. – Michelangelo

Trả lời

5

Vấn đề refresh tôi đã nhận được với một tham số truy vấn url chứa một 'chấm' là một vấn đề máy chủ.
Nguyên nhân là do cách tôi đối phó với html5mode (redirect index.html nếu không muốn nói là một nguồn lực tĩnh) trong các thiết lập máy chủ grunt

// 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) 
     ]; 
     } 
    } 
    }, 

tôi đã thay đổi

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

để

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

Tôi đã hoàn toàn sửa đổi mã. Tôi có thể sử dụng dấu chấm tốt vì vậy xin vui lòng ngã ba plunker để hiển thị nơi bạn đang nhận được một lỗi.

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

bạn sẽ sử dụng điều này như thế nào trong $ stateProvider.state()? – klode

+0

Tôi đã cập nhật mã, vui lòng xem lại và cho tôi biết lỗi của bạn ở đâu. – Enkode

+0

Như tôi đã nói, vấn đề sẽ không xảy ra với nhà nước nhưng khi ** tải lại ** trang bookDetails (làm mới trình duyệt khi trên sổ sách). – klode

2

Nếu bạn đang sử dụng connect-history-api-fallback trên máy chủ của mình (như lite-server), các URL có dấu chấm sẽ không được ghi đè theo mặc định.

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(); 
} 

Bắt đầu với phiên bản connect-history-api-fallback1.2.0 các URLs with dots are allowed và bạn có thể giải quyết this problem bằng aa rewrite roule

Ví dụ

Nếu URL của bạn với dấu chấm là /api/test/:id (ví dụ. /api/test/123.34) và bạn đời ứng dụng góc trong trang index.html bạn có thể thêm một viết lại cai trị với kết nối lịch sử-api-dự phòng như thế này

rewrites: [ 
    { 
    from: /^\/api\/test\/[0-9]+\.[0-9]+$/, 
    to: 'index.html' 
    } 
    } 
] 
Các vấn đề liên quan