可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
edited for clarification and modified example pseudo-code
I was trying to understand the concept of mvc and sometimes it gives me some serious headaches.
I was facing with a problem and trying to think a solution. I am using codeigniter and the problem is how to make different page titles and descriptions for different categories and searches in my web site.
Here is the solution I thought (I know it's not the best way the demonstrate it but don't stuck in details just look at the basic idea):
controller
$data['results'] = call model and get results
this->load->view(ad_details,$results);
ad_categories view:
foreach ($results as $key => $row) {
$ad_title = $row->title;
$ad_id = $row->id;
$ad_price = $row->price;
$ad_status = $row->status;
$ad_city = $row->city;
$ad_user = $row->user;
if ($key<1) {
// let's be sure even customers enter same info we got unique titles and descriptions for search engines
$data['title'] = "$ad_title $ad_id $ad_price";
$data['description'] = "Second Hand Autos for $ad_status from $ad_user in $ad_city";
this->load->view(header,$data);
<body>
}
$ad_description = $row->description;
<h2>$ad_title</h2>
<p>$ad_description</p>
}
</body>
<? this->load->view(footer); ?>
header_view file
<!doctype html>
<head>
<meta charset="utf-8">
<title><?=$title?></title>
<META NAME="description" CONTENT="<?=$description">
<META NAME="keywords" CONTENT="<?=$keywords?>" >
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="stylesheet" href="css/style.css">
<script src="js/libs/modernizr-2.0.6.min.js"></script>
</head>
<body>
The actual titles and descriptions can be quite different, there can be some exceptions and I may have to use different codes for different categories and different search pages. So, doing it in that way against MVC or is there better way to do that?
In that way, I’m trying to avoid using same foreach loops multiple times in controller or in views.
the actual titles and descriptions can be quite different, there can be some exceptions and i may have to use different codes for different categories and different search pages. So, is doing it in that way against mvc or is there better way to do that ?
回答1:
Edit: I've learned from reading the comments to this that you can't use $results[0]
in CodeIgniter, you have to use $results->row()
apparently - I'm leaving my answer as it was because it wasn't supposed to be 100% CI-specific, but bear it in mind.
Here's the way I'd have written your view:
<?php $this->load->view('header', array(
'title' => $results[0]->title.' '.$results[0]->id.' '.$results[0]->price,
'description' => 'Second hand autos for '.$results[0]->status.' from '.$results[0]->user.' in '.$results[0]->city
)); ?>
<body>
<h2><?php echo htmlspecialchars($results[0]->title); ?></h2>
<p><?php echo htmlspecialchars($results[0]->description); ?></p>
<?php foreach($results as $row): ?>
<!-- Deal with results -->
<?php endforeach; ?>
</body>
<? this->load->view('footer'); ?>
Here you can see I've eliminated the foreach loop except where you're actually dealing with each of the results in turn. Having said that, my personal opinion is that you're taking the "don't repeat yourself" mantra a little bit too far, to the extent that you're sacrificing code readability/maintainability for its sake. If combining multiple foreach loops into one makes the code more difficult to understand, don't do it.
I've also tried to cut down on the amount of PHP and variable assignments in the view, which is usually a good thing, but this too can be inconvenient if pushed too far. For instance, you might want to cut down on all the $results[0]->
stuff by doing this right at the top of your view:
$r = $results[0];
Then again, you might not. Whatever quacks your duck. :)
回答2:
Since MVC is a design pattern and not a syntax rule, you've a certain degree of freedom here. I see nothing wrong in using a view inside a view, and not only it's possibile in CI, but it's so thought out that you can call different views and nest them withouth having to pass the "secondary" view its set of data, as views are buffered and they will available to all anyways.
SO you can do something like:
controller:
$data['results'] = $this->your_model->get_details();
// this will be in the form of an array returned directly from the model
// i.e. the model code would look someting like:
// $data = array();
// foreach($query->result() as $row)
// {
// $data[] = $row;
// }
// return $data;
$this->load->view('ad_details',$data);
In ad_details.php:
<?php $this->load->view('header');?>
<!-- html code -->
<? $this->load->view('footer'); ?>
If you var_dump() it, you will see that both the header.php and footer.php will have a variable $results now, without having to pass it again.
回答3:
MVC is there to keep your life easier and your development faster, if you cannot call it from the controller level and it's permitted to call it inside the view, do so.
回答4:
Generally you want to have one model - one view with the relationship and data/flow controlled via some controller. A controller can manage multiple models and views but each distinct view should have a corresponding model.
It would be a good idea to read up on ASP NET MVC.
回答5:
Handle your logic in the controller.
in general, this means loop and conditionals which decide what to display stay out of the view. the view can use logic to decide how to display stuff, looping to create tables, etc.
put all this in the controller.
$data['results'] = call model and get results
$this->load->view(ad_details,$results);
foreach ($results as $key => $row) {
if ($key<1) {
// let's be sure even customers enter same info we got unique titles and descriptions for search engines
$data['title'] = "$ad_title $ad_id $ad_price";
$data['description'] = "Second Hand Autos for $ad_status from $ad_user in $ad_city";
this->load->view(header,$data);
}
this->load->view(body, data);