我有一个URL,它将允许我过滤课程列表。这是URL的格式:
www.xxxxx #/过滤器/全部课程/Languages-All-All/所有/小时(s)/所有///任何/所有1
通过这个url,我想要Course
作为type
, Languages
作为Category
, duration
在hour(s)
中的课程列表
这是客户端应用程序的URL(用Angular.js
编写)。我所做的是读取url中的参数,然后调用一个webservice,该webservice将为我提供具有给定生物的课程列表。
这个URL很难看,因为它包含了很多'All'通配符(客户端不喜欢它)。
我想删除'All'关键字。我面临的问题是,我将不再知道哪个关键字是相对于哪种类型的过滤器。第二个问题是,这个url可以发送给另一个人(另一个浏览器),我应该得到与第一个浏览器相同的结果。
解决方案,我看到(希望它不是唯一的一个)将过滤器作为键值,url将如下所示:
/过滤器/类型:课程/类别:语言……
这在少量过滤器中很好,但在大量过滤器(我有12个)的情况下很长。理想的解决方案是使用这样的URL:
/过滤器/课程/语言……
你知道我该怎么做吗?
您可以通过将url段与唯一的regexp模式匹配来实现类似http://www.springest.co.uk/agriculture-horticulture/animal-care的过滤。例如,他们使用daytime
作为日间过滤器,因为它不匹配任何其他过滤器,而对于职业级别过滤器,他们使用职业级别-[2-4]…
因此,我们的想法是确定只匹配唯一过滤器的模式,然后进行匹配并激活每个过滤器。在你的情况下,如果我们做以下假设:
- Hours是唯一具有数值 的过滤器
- 类型为
course
或other
,是保留值,没有过滤器可以匹配它们。 - 语言以
language-
开头
我们知道过滤器匹配一个单一的模式,如果一个片段是数字,它是小时,如果以语言开头,它是语言,如果课程或其他,它是类型。然后你的逻辑看起来像这样:
var App = angular.module('App', ['ngRoute']);
var patterns = {
type: /(course|other)/,
hours: /([0-9]+)/,
language: /language-(.*)/,
};
App.config(function ($routeProvider) {
$routeProvider
.when('/filter/:filter*', {templateUrl: 'aa.html', controller: 'FilterCtrl'})
.otherwise({redirectTo: '/'});
});
App.controller('FilterCtrl', function ($routeParams, $location) {
var segments = $routeParams.filter.split('/');
segments.forEach(function (el) {
for (var filter in patterns) {
var res = el.match(patterns[filter]);
if (res !== null) {
console.log("Activate filter ", filter, " with params", res[1]);
}
}
});
});
这种方法使得过滤非常灵活,所以你可以改变过滤器的顺序,也可以很容易地删除或添加新的过滤器,就像网站的情况。
您应该注意将来可能发生的更改,如果业务逻辑或命名约定的修改会破坏过滤器,因此明智地选择模式,希望我有所帮助。
我觉得这应该在后端部分处理。过滤器的类型可以从其名称中找出,除非某些过滤器名称出现在几个类型中,在这种情况下,唯一的解决方案是更改它们的名称以使它们唯一。如果标记之间没有重叠,问题就变得微不足道了。
我会用'/'分隔强制过滤器,用'-'分隔可选过滤器,让后端做脏排序。
为了简化事情,我将在应用过滤器的表中添加一个'seo_tag'字段(或一个名为seo_filters的新表),并在这些表之间进行唯一性验证。
由于您可以控制url,因此您确实应该使用旧的查询参数。它使Url看起来更好。
www.xxxxx #/过滤器?语言= all&课程= type&时间= 12
没有设置的查询参数,可以有一个默认值
使用$location.search()方法,您可以访问这些查询参数。