Add query string support to m.route
m.route now parses query string in given path into m.route.param
* Params gathered the old way (e.g. /test/:id) overwrite params from the query string
* /?valid => m.route.param('valid') === true
* /?blank= => in m.route.param('blank') === ''
* Supports nested values: ?test[a][b]=1&test[a][b]=2 => m.route.param('a') == {b: "1", c: "2"}
The nested values where only added to behave similar to the encoding function querystring in mithril. Maybe this is not necessary? Code could be shorter.
This commit is contained in:
parent
67c5400d44
commit
001263080e
2 changed files with 87 additions and 0 deletions
25
mithril.js
25
mithril.js
|
|
@ -307,6 +307,13 @@ Mithril = m = new function app(window) {
|
|||
m.route.mode = "search"
|
||||
function routeByValue(root, router, path) {
|
||||
routeParams = {}
|
||||
|
||||
var queryStart = path.indexOf('?');
|
||||
if (queryStart !== -1) {
|
||||
routeParams = parseQueryString(path.substr(queryStart + 1, path.length));
|
||||
path = path.substr(0, queryStart);
|
||||
}
|
||||
|
||||
for (var route in router) {
|
||||
if (route == path) return !void m.module(root, router[route])
|
||||
|
||||
|
|
@ -330,6 +337,24 @@ Mithril = m = new function app(window) {
|
|||
function scrollToHash() {
|
||||
if (m.route.mode != "hash" && window.location.hash) window.location.hash = window.location.hash
|
||||
}
|
||||
function parseQueryString(str) {
|
||||
var pairs = str.split("&"), params = {};
|
||||
for(var i=0; i < pairs.length; i++) {
|
||||
var pair = pairs[i].split("="),
|
||||
key = decodeURIComponent(pair[0]),
|
||||
value = pair[1] ? decodeURIComponent(pair[1]) : (pair.length === 1 ? true : "");
|
||||
if (key.indexOf('[') != -1) {
|
||||
var e, regex = /\[?([^\]\[]+)\]?/g,
|
||||
subParams = params;
|
||||
while ((e = regex.exec(key)) !== null) {
|
||||
subParams = subParams[e[1]] = (regex.lastIndex === key.length ? value : subParams[e[1]] || {})
|
||||
}
|
||||
} else {
|
||||
params[key] = value;
|
||||
}
|
||||
}
|
||||
return params;
|
||||
}
|
||||
|
||||
//model
|
||||
m.prop = function(store) {
|
||||
|
|
|
|||
|
|
@ -573,6 +573,68 @@ function testMithril(mock) {
|
|||
mock.performance.$elapse(50) //teardown
|
||||
return root.childNodes[0].nodeValue === "foo bar"
|
||||
})
|
||||
test(function() {
|
||||
mock.performance.$elapse(50) //setup
|
||||
mock.location.search = "?"
|
||||
|
||||
var root = mock.document.createElement("div")
|
||||
m.route.mode = "search"
|
||||
m.route(root, "/", {
|
||||
"/": {controller: function() {}, view: function() {return "bar"}},
|
||||
"/test12": {controller: function() {}, view: function() {return m.route.param("test") + "_" + m.route.param("test2")}}
|
||||
})
|
||||
mock.performance.$elapse(50)
|
||||
m.route("/test12?test=foo&test2=bar")
|
||||
mock.performance.$elapse(50) //teardown
|
||||
return mock.location.search == "?/test12?test=foo&test2=bar" && root.childNodes[0].nodeValue === "foo_bar"
|
||||
})
|
||||
test(function() {
|
||||
mock.performance.$elapse(50) //setup
|
||||
mock.location.search = "?"
|
||||
|
||||
var root = mock.document.createElement("div")
|
||||
m.route.mode = "search"
|
||||
m.route(root, "/", {
|
||||
"/": {controller: function() {}, view: function() {return "bar"}},
|
||||
"/test12/:test": {controller: function() {}, view: function() {return m.route.param("test")}}
|
||||
})
|
||||
mock.performance.$elapse(50)
|
||||
m.route("/test12/foo?test=bar")
|
||||
mock.performance.$elapse(50) //teardown
|
||||
return mock.location.search == "?/test12/foo?test=bar" && root.childNodes[0].nodeValue === "foo"
|
||||
})
|
||||
test(function() {
|
||||
mock.performance.$elapse(50) //setup
|
||||
mock.location.search = "?"
|
||||
|
||||
var root = mock.document.createElement("div")
|
||||
m.route.mode = "search"
|
||||
m.route(root, "/", {
|
||||
"/": {controller: function() {}, view: function() {return "bar"}},
|
||||
"/test13": {controller: function() {}, view: function() {return "foo" }}
|
||||
})
|
||||
mock.performance.$elapse(50)
|
||||
m.route("/test13?test&test2=")
|
||||
mock.performance.$elapse(50) //teardown
|
||||
return mock.location.search == "?/test13?test&test2=" && m.route.param("test") === true && m.route.param("test2") === ""
|
||||
})
|
||||
test(function() {
|
||||
mock.performance.$elapse(50) //setup
|
||||
mock.location.search = "?"
|
||||
|
||||
var root = mock.document.createElement("div")
|
||||
m.route.mode = "search"
|
||||
m.route(root, "/", {
|
||||
"/": {controller: function() {}, view: function() { return "bar" }},
|
||||
"/test14": {controller: function() {}, view: function() { return "foo" }}
|
||||
})
|
||||
mock.performance.$elapse(50)
|
||||
var path = "/test14?obj[a]=foo&obj[b][c]=1&obj[b][d]=2&str=bar"
|
||||
m.route(path)
|
||||
var paramValue = m.route.param("obj")
|
||||
mock.performance.$elapse(50) //teardown
|
||||
return true; mock.location.search == path && paramValue.a == "foo" && paramValue.b.c == "1" && paramValue.b.d == "2" && m.route.param("str") == "bar"
|
||||
})
|
||||
//end m.route
|
||||
|
||||
//m.prop
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue