问题描述
这是我用来在 OpenCart 中显示不同级别的类别菜单的代码.它可以工作,但每次单击后都会产生越来越多的XHR finished loading: POST
和XHR finished loading: GET
,有时会通过单击来停止页面:
Here is the code I used to show a category menu in OpenCart with different levels. It works, but after each click it produces more and more XHR finished loading: POST
and XHR finished loading: GET
s which stops the page by clicking sometimes:
<script type="text/javascript">
_url = '';
$(document).ready(function(){
$('#mnav a').on('click', function() {
var cat = $(this).attr('id');
_url = '&category_id=' + cat;
$.post('index.php?route=test/category/child' + _url,
function(data) {
if(data.length>10){
$('#mnav #sub').remove();
$(data).insertAfter($('#mnav #' + cat));
}
});
});
});
$.ajaxPrefilter(function( options, original_Options, jqXHR ) {
options.async = true;
});
</script>
HTML代码:
<div id="mnav" class="list-group">
<?php foreach ($categories as $category) { ?>
<a id="<?php echo $category['category_id']; ?>" class="list-group-item active"><?php echo $category['name']; ?></a>
<?php } ?>
</div>
控制器代码:
<?php
class ControllerTestCategory extends Controller {
public function index() {
if (isset($this->request->get['path'])) {
$parts = explode('_', (string)$this->request->get['path']);
} else {
$parts = array();
}
$data['category_id'] = 0;
if (isset($parts[0])) {
$data['category_id'] = $parts[0];
} else {
$data['category_id'] = 0;
}
if (isset($parts[1])) {
$data['child_id'] = $parts[1];
} else {
$data['child_id'] = 0;
}
$this->load->model('catalog/cat');
$data['categories'] = array();
$categories = $this->model_catalog_cat->getCategories(0);
foreach ($categories as $category) {
$children_data = array();
$filter_data = array(
'filter_category_id' => $category['category_id'],
'filter_sub_category' => true
);
$data['categories'][] = array(
'category_id' => $category['category_id'],
'name' => $category['name'],
'children' => $category['children'],
'products' => $category['products'],
'href' => $this->url->link('product/category', 'path=' . $category['category_id'])
);
}
$this->response->setOutput($this->load->view('test/category', $data));
}
public function child() {
if (isset($this->request->get['category_id'])) {
$this->load->model('catalog/cat');
$data['categories'] = array();
$categories = $this->model_catalog_cat->getCategories($this->request->get['category_id']);
$data['x'] = '<div id="sub">';
foreach ($categories as $category) {
$data['x'] .= '<li>' . $category['name'] . '</li>';
}
$data['x'] .= '</div>';
} else {
$data['x'] = 'NA';
}
$this->response->setOutput($this->load->view('test/category', $data));
}
}
SQL代码:
public function getCategories($parent_id = 0) {
$sql = "SELECT c.category_id, c.parent_id, cd.name,
(SELECT COUNT(DISTINCT ch.category_id) from category ch where ch.parent_id = c.category_id and cd.language_id = '" . (int)$this->config->get('config_language_id') . "') as children";
$sql .= " , (SELECT COUNT(DISTINCT p.product_id)
FROM product p
LEFT JOIN product_description pd ON (p.product_id = pd.product_id)
LEFT JOIN product_to_category p2c ON (p2c.product_id = p.product_id)
LEFT JOIN category_path cp ON (cp.category_id = p2c.category_id)
WHERE
pd.language_id = '" . (int)$this->config->get('config_language_id') . "' AND
p.status = '1' AND
p.date_available <= NOW()) AS items";
$sql .= " FROM category c LEFT JOIN category_description cd ON (c.category_id = cd.category_id) WHERE c.parent_id = '" . (int)$parent_id . "' AND cd.language_id = '" . (int)$this->config->get('config_language_id') . "' AND c.status = '1' ORDER BY c.sort_order, LCASE(cd.name)";
$query = $this->db->query($sql);
return $query->rows;
}
如果您能通过提供所有必要的JavaScript,jQuery和JSON代码来帮助我,我将不胜感激,因为我对这些主题的了解很少:-(
I'd highly appreciate if you kindly help me by providing all necessary JavaScript, jQuery and JSON codes because I know these subjects with little :-(
推荐答案
您可以将发布请求的结果存储在javascript数组中,以便重复使用,请参见以下内容:
You could store the result of the post request in a javascript array, so you could reuse it, see following please:
var cachedObj = [];
$(document).ready(function(){
$('#mnav a').on('click', function() {
var cat = $(this).attr('id');
_url = '&category_id=' + cat;
getData(cat, _url); //<-- Get data from ajax or cache
});
});
//This function replaces the $.post call (just for example)
function dummyPost(id, url){
//url should be used to make the post call
var data = "<span class='sub'>Test " + id + "</span>";
return data;
}
function getData(id, url){
//Try to get data from cache
var data;
if(cachedObj[url]) {
data = cachedObj[url];
console.log("Data retrived from cache");
}
else {
data = dummyPost(id, url);
cachedObj[url] = data;
console.log("Data retrived from post");
}
$('#mnav .sub').remove();
//$(data).insertAfter($('#mnav #' + id));
$('#mnav #' + id).append($(data));
}
.sub{
color: red;
font-weight: bold;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="mnav" class="list-group">
<a id="1" class="list-group-item active">One</a>
<a id="2" class="list-group-item active">Two</a>
<a id="3" class="list-group-item active">Three</a>
</div>
我已经制作了dummyPost
函数,为了执行发布请求,应该对其进行修改.
I've maked the dummyPost
function that should be modified in order to do the post request.
您可能会在我的示例日志中看到,第一次单击链接时,它会使用"post"检索其子菜单,而下一次,它将从缓存数组cachedObj
中获取数据.
You could see in my example's log, that the first time you click on a link it retrieves his submenu with a "post", the next times instead, it get data from the cached array cachedObj
.
我希望它能对您有所帮助.再见.
I hope it helps you. Bye.
更新:应用于您的代码应类似于:
Update:Applied to your code should be like:
<script type="text/javascript">
var cachedObj = []; //<-- Add an array to cache submenus
//Add a function to retrieves data from cache or REST
function getData(url){
//Try to get data from cache
if(cachedObj[url]) {
console.log("Data retrived from cache");
}
else {
$.ajax({
type: 'GET',
url: 'index.php?route=test%2Fcategory%2Fchild' + url,
success: function(data) {
cachedObj[url] = data;
console.log("Data retrived from post");
}),
async:false
});
}
return cachedObj[url];
}
$(document).ready(function(){
$('#mnav a').on('click', function() {
var cat = $(this).attr('id');
var url = '&category_id=' + cat;
var data = getData(url); //<-- Call the new function to get data
if(data.length>10){
$('#mnav #sub').remove();
$(data).insertAfter($('#mnav #' + cat));
}
});
});
</script>
我无法对其进行测试,因此可能包含一些错误.
I can't test it, so it could be contains some errors.
这篇关于如何使用Ajax和JSON制作下拉菜单?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!