Sử dụng Backbone, tôi có thể lấy tên của tuyến đường hiện tại không? Tôi biết cách liên kết với các sự kiện thay đổi tuyến đường, nhưng tôi muốn có thể xác định tuyến đường hiện tại vào các thời điểm khác, giữa các thay đổi.
Sử dụng Backbone, tôi có thể lấy tên của tuyến đường hiện tại không? Tôi biết cách liên kết với các sự kiện thay đổi tuyến đường, nhưng tôi muốn có thể xác định tuyến đường hiện tại vào các thời điểm khác, giữa các thay đổi.
Câu trả lời:
Nếu bạn đã khởi tạo Bộ định tuyến trong ứng dụng của mình, dòng sau sẽ trả về đoạn hiện tại:
Backbone.history.getFragment();
Từ tài liệu Backbone.js :
"[...] Lịch sử đóng vai trò là bộ định tuyến toàn cầu (trên mỗi khung) để xử lý các sự kiện trao đổi băm hoặc PushState, khớp với lộ trình phù hợp và kích hoạt các cuộc gọi lại. Bạn không nên tự mình tạo một trong số đó - bạn nên sử dụng tham chiếu tới Backbone.history sẽ được tạo tự động cho bạn nếu bạn sử dụng Bộ định tuyến với các tuyến đường. [...] "
Nếu bạn cần tên của hàm bị ràng buộc với đoạn đó, bạn có thể tạo một cái gì đó như thế này trong phạm vi của Bộ định tuyến của bạn:
alert( this.routes[Backbone.history.getFragment()] );
Hoặc như thế này từ bên ngoài bộ định tuyến của bạn:
alert( myRouter.routes[Backbone.history.getFragment()] );
Backbone.history.getFragment()
, bởi vì Backbone.history.fragment
là một tài sản ẩn riêng tư.
Câu trả lời của Robert rất thú vị, nhưng thật đáng buồn, nó sẽ chỉ hoạt động nếu hàm băm chính xác như được xác định trong tuyến đường. Ví dụ, nếu bạn có một tuyến đường cho user(/:uid)
nó sẽ không được khớp nếu đó Backbone.history.fragment
là "user"
hoặc "user/1"
(cả hai trường hợp sử dụng rõ ràng nhất cho tuyến đường đó). Nói cách khác, nó sẽ chỉ tìm thấy tên gọi lại phù hợp nếu hàm băm chính xác "user(/:uid)"
(rất khó xảy ra).
Vì tôi cần chức năng này, tôi đã mở rộng Backbone.Router
với một current
chức năng sử dụng lại một số mã mà đối tượng Lịch sử và Bộ định tuyến sử dụng để khớp với đoạn hiện tại so với các Tuyến được xác định để kích hoạt cuộc gọi lại thích hợp. Đối với trường hợp sử dụng của tôi, nó nhận tham số tùy chọn route
, nếu được đặt thành bất kỳ giá trị trung thực nào sẽ trả về tên hàm tương ứng được xác định cho tuyến. Nếu không, nó sẽ trả về đoạn băm hiện tại từ Backbone.History.fragment
.
Bạn có thể thêm mã vào Mở rộng hiện tại nơi bạn khởi tạo và thiết lập bộ định tuyến đường trục.
var Router = new Backbone.Router.extend({
// Pretty basic stuff
routes : {
"home" : "home",
"user(:/uid)" : "user",
"test" : "completelyDifferent"
},
home : function() {
// Home route
},
user : function(uid) {
// User route
},
// Gets the current route callback function name
// or current hash fragment
current : function(route){
if(route && Backbone.History.started) {
var Router = this,
// Get current fragment from Backbone.History
fragment = Backbone.history.fragment,
// Get current object of routes and convert to array-pairs
routes = _.pairs(Router.routes);
// Loop through array pairs and return
// array on first truthful match.
var matched = _.find(routes, function(handler) {
var route = handler[0];
// Convert the route to RegExp using the
// Backbone Router's internal convert
// function (if it already isn't a RegExp)
route = _.isRegExp(route) ? route : Router._routeToRegExp(route);
// Test the regexp against the current fragment
return route.test(fragment);
});
// Returns callback name or false if
// no matches are found
return matched ? matched[1] : false;
} else {
// Just return current hash fragment in History
return Backbone.history.fragment
}
}
});
// Example uses:
// Location: /home
// console.log(Router.current()) // Outputs 'home'
// Location: /user/1
// console.log(Router.current(true)) // Outputs 'user'
// Location: /user/2
// console.log(Router.current()) // Outputs 'user/2'
// Location: /test
// console.log(Router.current(true)) // Outputs 'completelyDifferent'
Tôi chắc chắn một số cải tiến có thể được thực hiện, nhưng đây là một cách tốt để giúp bạn bắt đầu. Ngoài ra, thật dễ dàng để tạo chức năng này mà không cần mở rộng đối tượng Tuyến đường. Tôi đã làm điều này bởi vì đó là cách thuận tiện nhất cho việc thiết lập của tôi.
Tôi chưa thử nghiệm điều này đầy đủ, vì vậy xin vui lòng cho tôi biết nếu có bất cứ điều gì đi về phía nam.
Tôi đã thực hiện một số thay đổi cho hàm, vì vậy thay vì trả về tên gọi lại hàm băm hoặc tuyến đường, tôi trả về một đối tượng có đoạn, thông số và tuyến để bạn có thể truy cập tất cả dữ liệu từ tuyến hiện tại, giống như bạn đi từ tuyến đường- biến cố.
Bạn có thể thấy những thay đổi dưới đây:
current : function() {
var Router = this,
fragment = Backbone.history.fragment,
routes = _.pairs(Router.routes),
route = null, params = null, matched;
matched = _.find(routes, function(handler) {
route = _.isRegExp(handler[0]) ? handler[0] : Router._routeToRegExp(handler[0]);
return route.test(fragment);
});
if(matched) {
// NEW: Extracts the params using the internal
// function _extractParameters
params = Router._extractParameters(route, fragment);
route = matched[1];
}
return {
route : route,
fragment : fragment,
params : params
};
}
Xem mã trước để biết thêm nhận xét và giải thích, chúng trông giống nhau.
_.find
hàm là this
, do đó loại bỏ sự cần thiết của Router
biến (@DanAbramov đã làm điều này rồi).
Marionette.AppRouter
, hãy mở rộng bộ định tuyến của bạn với chức năng trên, nhưng thay thế Router.appRoutes
cho Router.routes
.
Để nhận tuyến gọi (hoặc url) từ trình xử lý tuyến được gọi, bạn có thể nhận tuyến bằng cách kiểm tra
Backbone.history.location.href ... url đầy đủ Backbone.history.location.search ... chuỗi truy vấn bắt đầu từ đâu?
Tôi đã đến đây trong quá trình tìm kiếm câu trả lời này vì vậy tôi đoán tôi nên để lại những gì tôi đã tìm thấy.
Nếu bạn sử dụng cài đặt gốc cho Bộ định tuyến, bạn cũng có thể bao gồm nó để lấy đoạn 'thực'.
(Backbone.history.options.root || "") + "/" + Backbone.history.fragment
Dưới đây là một chút dài dòng hơn (hoặc tùy theo khẩu vị của bạn, dễ đọc hơn) phiên bản của câu trả lời của Simon :
current: function () {
var fragment = Backbone.history.fragment,
routes = _.pairs(this.routes),
route,
name,
found;
found = _.find(routes, function (namedRoute) {
route = namedRoute[0];
name = namedRoute[1];
if (!_.isRegExp(route)) {
route = this._routeToRegExp(route);
}
return route.test(fragment);
}, this);
if (found) {
return {
name: name,
params: this._extractParameters(route, fragment),
fragment: fragment
};
}
}
Nếu bạn nhìn vào nguồn cho Router
, bạn sẽ thấy rằng khi bộ định tuyến kích hoạt sự kiện nói rằng có gì đó thay đổi, nó sẽ chuyển tên với tên là "tuyến đường: tên".
http://documentcloud.github.com/backbone/docs/backbone.html#section-84
Bạn luôn có thể nối sự kiện "tuyến đường" trên bộ định tuyến và lưu trữ để có được tuyến đường hiện tại.
route
sự kiện nếu trigger
không true
(được khuyến nghị & mặc định).