- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我正在尝试使用 MVC 范例重构我的应用。
我的网站显示图表。 URL 的形式为
我正在使用 Apache Rewrite 将所有请求路由到 index.php,因此我在 PHP 中进行 URL 解析。
我正在进行一项持久的任务,即在选择某个页面时将 active
类添加到我的导航链接中。具体来说,我有类别级导航和图表级子导航。我的问题是,在保持 MVC 精神的同时做到这一点的最佳方法是什么?
在我重构之前,由于 nav 变得相对复杂,我决定将它放入一个数组中:
$nav = array(
'25th_monitoring' => array(
'title' => '25th Monitoring',
'charts' => array(
'month_over_month' => array(
'default' => 'month_over_month?who=total&deal=loan&prev='.date('MY', strtotime('-1 month')).'&cur='.date('MY'),
'title' => 'Month over Month'),
'cdu_tracker' => array(
'default' => 'cdu_tracker',
'title' => 'CDU Tracker')
)
),
'internet_connectivity' => array(
'title' => 'Internet Connectivity',
'default' => 'calc_end_to_end',
'charts' => array(
'calc_end_to_end' => array(
'default' => 'calc_end_to_end',
'title' => 'calc End to End'),
'quickcontent_requests' => array(
'default' => 'quickcontent_requests',
'title' => 'Quickcontent Requests')
)
)
);
同样,我需要知道当前类别和正在访问的当前图表。我的主导航是
<nav>
<ul>
<?php foreach ($nav as $category => $category_details): ?>
<li class='<?php echo ($current_category == $category) ? null : 'active'; ?>'>
<a href="<?php echo 'http://' . $_SERVER['SERVER_NAME'] . '/' . $category . '/' . reset(reset($category_details['charts'])); ?>"><?php echo $category_details['title']; ?></a>
</li>
<?php endforeach; ?>
</ul>
</nav>
和子导航类似,检查 current_chart 而不是 current_category。
之前,在解析过程中,我通过 /
分解 $_SERVER['REQUEST_URI']
,并将片段分解为 $current_category
和 $current_chart
。我在 index.php 中这样做。现在,我觉得这不符合字体 Controller 的精神。来自 Symfony 2's docs 等引用文献,似乎每条路线都应该有自己的 Controller 。但是,我发现自己必须多次定义当前类别和图表,或者在模板文件本身(这似乎不符合 MVC 的精神)中,或者在模型中的任意函数中(然后必须由多个 Controller 调用,这似乎是多余的)。
此处的最佳做法是什么?
更新:这是我的前端 Controller 的样子:
// index.php
<?php
// Load libraries
require_once 'model.php';
require_once 'controllers.php';
// Route the request
$uri = str_replace('?'.$_SERVER['QUERY_STRING'], '', $_SERVER['REQUEST_URI']);
if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && (!empty($_GET)) && $_GET['action'] == 'get_data') {
$function = $_GET['chart'] . "_data";
$dataJSON = call_user_func($function);
header('Content-type: application/json');
echo $dataJSON;
} elseif ( $uri == '/' ) {
index_action();
} elseif ( $uri == '/25th_monitoring/month_over_month' ) {
month_over_month_action();
} elseif ( $uri == '/25th_monitoring/cdu_tracker' ) {
cdu_tracker_action();
} elseif ( $uri == '/internet_connectivity/intexcalc_end_to_end' ) {
intexcalc_end_to_end_action();
} elseif ( $uri == '/internet_connectivity/quickcontent_requests' ) {
quickcontent_requests_action();
} else {
header('Status: 404 Not Found');
echo '<html><body><h1>Page Not Found</h1></body></html>';
}
?>
似乎当 month_over_month_action() 被调用时,例如,由于 Controller 知道 current_chart 是 month_over_month,它应该传递它。这就是我被绊倒的地方。
最佳答案
这方面没有“最佳实践”。虽然,有一些比其他更常用,还有一些是非常糟糕的想法(不幸的是,这两组往往会重叠)。
虽然从技术上讲这不是 MVC 设计模式的一部分,但在应用于 Web 时,您的应用程序需要知道要初始化哪个 Controller 以及调用什么方法。
正在做 explode()
收集这类信息不是个好主意。它既难以调试又难以维护。更好的解决方案是使用正则表达式。
基本上,您最终会得到一个路由列表,其中包含一个正则表达式和一些回退值。您遍历该列表并在拳头匹配上提取数据并应用默认值,其中缺少数据。
这种方法还可以让您在参数顺序方面拥有更广泛的可能性。
为了使解决方案更易于使用,您还可以添加将符号字符串转换为正则表达式的功能。
例如(取 self 的一些单元测试):
符号: test[/:id]
表达式:#^/test(:?/(?P<id>[^/\.,;?\n]+))?$#
符号: [[/:minor]/:major]
表达式:#^(:?(:?/(?P<minor>[^/\.,;?\n]+))?/(?P<major>[^/\.,;?\n]+))?$#
符号: user/:id/:nickname
表达式:#^/user/(?P<id>[^/\.,;?\n]+)/(?P<nickname>[^/\.,;?\n]+)$#
虽然创建这样的生成器并不那么容易,但它可以很好地重用。恕我直言,花在制作它上的时间是值得的。此外,使用 (?P<key>expression)
正则表达式中的构造为您提供了来自匹配路由的非常有用的键值对数组。
决定将哪个菜单项突出显示为 active
应该始终是当前 View 实例的责任。
更复杂的问题是做出此类决定所需的信息从何而来。 View 实例可用的数据有两个来源:由 Controller 传递给 View 的信息和数据,即从模型层请求的 View 。
The controller in MVC takes the user's input and, based on this input, it changes the state of current view and model layer, by passing said values. Controller should not be extracting information from model layer.
恕我直言,在这种情况下更好的方法是在模型层上中继有关菜单内容和其中当前事件元素的信息。虽然可以对 View 中的当前事件元素进行硬编码并中继 Controller 传递的信息,但 MVC 通常用于大型应用程序,这种做法最终会伤害到您。
The view in MVC design pattern is not a dumb template. It's a structure, that is responsible for UI logic. In context of Web that would mean creating a response from multiple template, when necessary, or sometimes just simply sending an HTTP location header.
关于php - MVC 中的路由、导航和状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14596934/
我的 Angular 应用程序中有以下代码。 app.config(function($routeProvider, $locationProvider) { $locationProvider
这就是我在 Backbone 中进行路由的方式,在决定调用哪个外部模板之前,首先获取路由及其参数。我觉得这很灵活。 var Router = Backbone.Router.extend({
我是 MEAN 堆栈领域的新手,我对 Angular 路线有一些疑问。为什么我应该在客户端重新创建后端已经用express.js创建的路由,有什么好处?这是 Angular.js 工作的唯一方式吗?我
我可以设置一条从根级 URL 进行映射的路由吗? http://localhost:49658/ 我使用的是 VS2010 内置 Web 服务器。 尝试使用空白或单斜杠 URL 字符串设置路由不起作用
我有一个现有的应用程序 Rails 3.2.17和 Angular js。我想在现有应用程序中包含 Activeadmin。 我遵循了 active-admin post from ryan bate
我正在关注 this Angular 中的路由教程,它就是行不通。当我使用“comp”选择器放置它的 HTML 代码时,它可以工作,但是当我尝试使用路由器 socket 对其进行路由时,它只显示来自
多个路由通过路由器进行管理。 前端路由的概念和原理 (编程中的) 路由 (router)就是一组 key-value 对应关系,分为:后端路由和前端路由 后端路由
服务器需要根据不同的URL或请求来执行不一样的操作,我们可以通过路由来实现这个步骤。 第一步我们需要先解析出请求URL的路径,我们引入url模块。 我们来给onRequest()函数加上一些逻辑
我正在为 Angular 6 应用程序设置路由,我想要一条可以匹配可变数量的段的路由。目前我有一个看起来像这样的路由配置: const routes: Routes = [ { path: '',
用户将点击电子邮件中的链接,如下所示: do-something/doSomething?thing=XXXXXXXXXXX 如何在路由器中定义路由并订阅获取参数? 目前在我的路由器中: {
我有一个具有以下结构的 Angular (4) 应用程序: app.module bi.module auth.module 路由应该是: / -> redirect to /home /
我正在使用 WCF 4 路由服务,并且需要以编程方式配置服务(而不是通过配置)。我见过的这样做的例子很少见,创建一个 MessageFilterTable 如下: var fi
我需要创建一个“路由”服务。我正在尝试使用 .Net 的 System.ServiceModel.Routing.IRequestReplyRouter我可以让它只在 HTTP 模式下工作,而不是在
例如,链接: /shop/phones/brend/apple/display/retina/color/red 在哪里: phones - category alias brend -
非常基本的问题,我很惊讶我找不到答案。我刚刚开始研究 django 并进行了开箱即用的安装。创建了一个项目并创建了一个应用程序。 urls.py 的默认内容很简单: urlpatterns = [
我已经实现了 WCF 路由服务;我还希望该服务(或类似的 WCF 服务)以规定的和统一的(与内容无关的)方式转换有效负载。例如,有效负载将始终采用 Foo 的形式。我想把它作为Bar在所有情况下。我很
我想使用 $locationProvider.html5Mode(true); 在 angularJs 中删除 # 哈希;但这导致所有 URL 都通过 angularJs 进行路由。我如何设置它以便只
我要听导航开始事件并判断其是否url属性是 /logout . 如果是这样,路由器应该停止触发连续事件,例如 路线已识别 , GuardsCheckStart , ChildActivationSta
有人可以解释我如何使用参数路由到 URL 吗? 例如id 喜欢点击产品并通过Id打开产品的更多信息。 我的路由到目前为止... angular.module('shop', ["cus
我目前正在 Angular: 7.2.14 上构建,想看看是否有人可以解释如何使用路由保护、共享服务或其他方式等重定向查询参数。 我试图解决的问题要求查询参数从根 Uri 路径传入,然后将路由重定向到
我是一名优秀的程序员,十分优秀!