9

Tôi muốn chặn mọi thay đổi tuyến đường bằng Sammy trước tiên phải kiểm tra xem có hành động đang chờ xử lý hay không. Tôi đã làm điều này bằng cách sử dụng API sammy.before và tôi trả về false để hủy tuyến đường. Điều này giúp người dùng trên 'trang' nhưng nó vẫn thay đổi băm trong thanh địa chỉ của trình duyệt và thêm tuyến đường vào lịch sử của trình duyệt. Nếu tôi hủy bỏ các tuyến đường, tôi không muốn nó trong thanh địa chỉ cũng không phải lịch sử, nhưng thay vào đó tôi hy vọng địa chỉ để ở lại giống nhau.Hủy lộ trình bằng Sammy.js mà không ảnh hưởng đến lịch sử

Hiện tại, để giải quyết vấn đề này, tôi có thể gọi window.history.back (yuk) để quay lại vị trí ban đầu trong lịch sử hoặc sammy.redirect. Cả hai đều ít hơn lý tưởng.

Có cách nào để làm cho sammy thực sự hủy tuyến đường để nó vẫn nằm trên tuyến đường/trang hiện tại, để lại thanh địa chỉ như vậy và không thêm vào lịch sử không?

Nếu không, có thư viện định tuyến nào khác sẽ thực hiện việc này không?

sammy.before(/.*/, function() { 
    // Can cancel the route if this returns false 
    var response = routeMediator.canLeave(); 

if (!isRedirecting && !response.val) { 
    isRedirecting = true; 
    // Keep hash url the same in address bar 
    window.history.back(); 
    //this.redirect('#/SpecificPreviousPage'); 
} 
else { 
    isRedirecting = false; 
} 
return response.val; 
}); 

Trả lời

17

Trong trường hợp ai đó truy cập vào đây, đây là nơi tôi đã kết thúc. Tôi quyết định sử dụng tính năng context.setLocation của sammy để xử lý đặt lại tuyến đường.

sammy.before(/.*/, function() { 
    // Can cancel the route if this returns false 
    var 
     context = this, 
     response = routeMediator.canLeave(); 

    if (!isRedirecting && !response.val) { 
     isRedirecting = true; 
     toastr.warning(response.message); // toastr displays the message 
     // Keep hash url the same in address bar 
     context.app.setLocation(currentHash); 
    } 
    else { 
     isRedirecting = false; 
     currentHash = context.app.getLocation(); 
    } 
    return response.val; 
}); 
+0

Hahaha John, tôi đến đây bằng cách tìm kiếm thêm thông tin về làm thế nào bạn đạt được điều này trong loạt SPA của bạn :-) –

1

Khi sử dụng mã được cung cấp trong phạm vi câu hỏi và trả lời, bạn phải nhận thấy rằng con đường bạn hủy cũng sẽ bị chặn cho tất cả các cuộc gọi trong tương lai, routeMediator.canLeave sẽ không được đánh giá lại. Gọi một tuyến đường hai lần và hủy bỏ nó tùy thuộc vào trạng thái hiện tại là không thể với điều này.

+1

Hmmm. Tôi tò mò tại sao bạn nói vậy. Tôi đã sử dụng mã này và không chặn các cuộc gọi trong tương lai tới canLeave. Bạn có thể xây dựng? Nếu tôi có lỗi, tôi muốn hiểu cách khắc phục. –

+0

Tài liệu Sammy trước đây cho biết: "Nếu bất kỳ cuộc gọi lại nào trả về sai, thực hiện bất kỳ cuộc gọi lại nào nữa và chính tuyến đường đó sẽ bị tạm dừng". - đây là những gì tôi đã quan sát với mã ở trên. Điều này chỉ xảy ra khi truy cập vào các tuyến đường bị chặn liên tiếp hai lần. Khi truy cập một tuyến đường khác giữa mọi thứ hoạt động tốt. –

+2

Tuyến đường bị tạm dừng, có. Nhưng nó không nói rằng các cuộc gọi trong tương lai đến tuyến đường này được ngăn chặn. Tôi không thấy hành vi này, tôi có thể ngăn nó rời đi, và sau đó nó vẫn gọi nó lần sau. –

0

Tôi có thể tạo ra kết quả tương tự như John Papa đã làm khi anh ấy sử dụng SammyJS trong khóa học SPA/Knockout.

Tôi đã sử dụng Crossroads JS làm bộ định tuyến, dựa trên Hasher JS để nghe các thay đổi URL "được phát ra" bởi trình duyệt.

mẫu mã là:

hasher.changed.add(function(hash, oldHash) { 
    if (pageViewModel.isDirty()){ 
     console.log('trying to leave from ' + oldHash + ' to ' + hash); 

     hasher.changed.active = false; 
     hasher.setHash(oldHash); 
     hasher.changed.active = true; 

     alert('cannot leave. dirty.'); 
    } 
    else { 
     crossroads.parse(hash); 
     console.log('hash changed from ' + oldHash + ' to ' + hash); 
     } 
}); 
0

Sau khi xem xét lại một dự án lớn tuổi và có một tình huống tương tự, tôi muốn chia sẻ cách tiếp cận khác, chỉ trong trường hợp ai đó đang chỉ đạo ở đây.

Điều cần thiết về cơ bản là mẫu "bảo vệ xác thực" hiện đại để chặn các trang và chuyển hướng dựa trên thông tin đăng nhập.

gì làm việc tốt là sử dụng Sammy.around(callback) như đã định nghĩa ở đây: Sammy.js docs: Sammy.Application around(callback)

Sau đó, bạn chỉ cần thực hiện như sau ...

(function ($) { 
    var app = Sammy("body"); 

    app.around(checkLoggedIn); 

    function canAccess(hash) { 
     /* access logic goes here */ 
     return true; 
    } 

    // Authentication Guard 
    function authGuard(callback) { 
     var context = this; 
     var currentHash = app.getLocation(); 
     if (!canAccess(currentHash)) { 
      // redirect 
      context.redirect("#/login"); 
     } 
     else { 
      // execute the route path 
      callback(); 
     } 
    }; 

})(jQuery);