本来在 HTML 中可以直接调用后端的 url_for 的,比如:
<script> var url = "{{ url_for('site.index') }}"; </script>
不过如果是外部引用的 js 的话,就没办法(除非以 HTML data 属性作为中介进行传递,但略麻烦),所以就写了个前端的 urlFor,和后端的 url_for 对应。
首先在后端加入这一段代码:
rules = {} for endpoint, _rules in iteritems(app.url_map._rules_by_endpoint): if any(item in endpoint for item in ['_debug_toolbar', 'debugtoolbar', 'static']): continue rules[endpoint] = [{'rule': rule.rule} for rule in _rules] app.jinja_env.globals.update({ 'rules': rules, })
然后在前端加入以下代码:
// Find out params in routing rules var pattern = new RegExp("<[^:]*:?([^>]+)>", "g"); var result = null; $.each(g.rules, function (endpoint, rules) { $.each(rules, function (index, rule) { rule.params = []; while ((result = pattern.exec(rule.rule)) !== null) { rule.params.push(result[1]); } }); }); /** * Check whether str ends with suffix. * @param str * @param suffix * @returns {boolean} */ function endsWith(str, suffix) { return str.indexOf(suffix, str.length - suffix.length) !== -1; } /** * Generate url for the endpoint. * urlFor(endpoint [, parameters]) * @param endpoint * @param parameters * @returns url for the endpoint. */ function urlFor(endpoint, parameters) { var url = null, params = [], maxMatchDegree = 0.0, keys; parameters = ($.type(parameters) !== 'undefined') ? parameters : {}; if (g.rules[endpoint] === undefined) { throw new Error("Uncorrect endpoint in " + "urlFor(\"" + endpoint + "\", " + JSON.stringify(parameters) + ")"); } keys = $.map(parameters, function (value, key) { return key; }); // Find the first matched rule among rules in this endpoint. $.each(g.rules[endpoint], function (index, rule) { var match = true, currentMatchDegree = 0.0; $.each(rule.params, function (index, param) { if ($.inArray(param, keys) === -1) { match = false; return false; } }); if (match) { currentMatchDegree = parseFloat(rule.params.length) / keys.length; if (currentMatchDegree > maxMatchDegree || url === null) { maxMatchDegree = currentMatchDegree; url = rule.rule; params = rule.params; } } }); if (url) { $.each(keys, function (index, key) { // Build in params if ($.inArray(key, params) > -1) { url = url.replace(new RegExp("<[^:]*:?" + key + ">"), parameters[key]); } else { // Query string params if (url.indexOf("?") === -1) { url += "?"; } if (!endsWith(url, '?')) { url += "&"; } url += key + "=" + parameters[key]; } }); } else { throw new Error("Uncorrect parameters in urlFor(\"" + endpoint + "\", " + JSON.stringify(parameters) + ")"); } return url; }
使用方法:
url_for('site.index') → '/' url_for('user.view', {uid: 1}) → '/user/1' url_for('user.view', {uid: 1, other:'other'}) → '/user/1?other=other' url_for('user.view', {other: 'other'}) → Uncorrect parameters in urlFor("user.view", {other:'other'})
![]() | 1 hustlzp OP 漏了一个地方,需要提将 rules 赋予 JS 全局变量 g 中: <script> g.rules = {{ rules|safe }}; </script> |
![]() | 2 dagger 2015-07-16 21:26:35 +08:00 重度flask瘾患者啊~ 话说这是直接把py翻译到js的吗? |