我一直试图弄清楚这一点,虽然我发现网上的各种例子已经设法完全混淆,因为似乎没有一点与我想做的完全匹配。
我正在构建一个Joomla组件,前端有一个视图。在默认模板('default.php')中,创建了两个divs
。一个包含项目列表,另一个包含空白。我有一些代码可以让我点击其中一个列出的项目并返回该项目唯一的ID。然后我想获取该ID并在Ajax调用中使用它来从数据库中的表中检索数据项。
该组件名为'com_pub',它应该显示每个组件的pubs和info列表。
我有一个名为controllers的文件夹(即'com_pub/controllers
'),我有一个名为'pubitems.php'的控制器,它只是扩展了JController类:
<?php
defined('_JEXEC') or die("Resricted Access!");
class PubControllerPubitems extends JController
{
}
?>
当我显示初始页面
时,此功能正常我在前端的'controllers'文件夹中创建了一个名为'pubitems.json.php'的新控制器,其中包含以下代码:
<?php
defined('_JEXEC') or die;
class ContentFetchPubitems extends JController
{
public function RetrieveContent()
{
echo(json_encode($data));
return;
}
}
我还在'tmpl'文件夹中创建了一个'content_response'文件:
<?php
echo "Dummy Response";
?>
在我的'default.php'文件中(位于视图的'tmpl'文件夹中)我有一个脚本,它使用JQuery从列表中获取所选的id,然后进行Ajax调用:
<script>
jQuery(".tocli").click(function(){
alert(this.id);
url = 'index.php&option=com_pub&controller=pubitems&task=RetrieveContent&tmpl=content_response&format=raw&dataType=json';
var jqxhr = jQuery.ajax(url,function(result){
alert("success");
})
.fail(function() {
alert( "Error: " );
})
.always(function() {
alert( "Finished: " + jqxhr.statusText);
});
});
</script>
Ajax调用所针对的功能显然必须做的不仅仅是回显消息,并且当我得到基本的工作时,它将从数据库中获取数据。
jQuery确实返回变量'this.id',这在警报中正确显示,但我现在甚至没有尝试在Ajax调用中发送它 - 我只是想接听电话在基本水平上运作(如果这是有道理的)。
其他警报有效,但'。success'不会被触发,'。'''显示'已完成:未找到',HTTPFox
显示为404 error
}。
所以我认为这意味着Ajax调用甚至没有进入'content_response'文件,并且url中的内容是错误的。根本问题在于我并没有真正了解网址的构建(可能还有其他问题 - 我还在学习)。我已经尝试更改网址中的各种元素,但没有取得任何成功。
我也不清楚我是否正确设置了控制器和其他文件。这样做似乎有很多不同的方法,我看到的很多东西都与其他帖子相矛盾,让我很困惑。
我为这么长的帖子道歉,但我想尽可能地清楚我要做的事情以及到目前为止我所做的事情。对真正理解Joomla 3.1的人的任何指导都将非常感激。
这是基于我在Lodder发现非常有用的评论之后所做的其他工作的更新,他发现了网址中的错误。不知道我是否应该以这种方式做到这一点,但有人可能会告诉我,如果我不是。
我更正了网址后,我根据反复试验和更多网络搜索进行了其他一些更改:
1)我摆脱了对模板的引用(tmpl = content_response),因为我突然意识到我正在尝试使用jQuery将ajax调用的结果插入到现有页面中,因此不希望成为加载不同的模板。
2)我更改了url的'task'元素,以包含控制器的名称以及我正在调用的函数(所以task = pubitems.RetrieveContent而不仅仅是task = RetrieveContent)。
3)我摆脱了url的'dataType = json'部分,但是留下了'format = raw'。
4)我创建了一个名为pubitems.raw.php的新控制器来保存RetrieveContent函数。
5)我在警报上添加了一些信息,看看我是否能获得有关ajax进程的更多信息。
所以现在我只使用default.php模板中的脚本,如下所示:
<script>
jQuery(".toc,li").click(function(){
alert(this.id);
var data_to_send = {'id': this.id};
alert(data_to_send);
url = 'index.php?option=com_pub&controller=pubitems&task=pubitems.RetrieveContent&data=data_to_send&format=raw';
var jqxhr = jQuery.ajax(url)
.done(function(result) {
alert("Success: " + jqxhr.status + " " + jqxhr.statusCode() + " " + jqxhr.statusText);
})
.fail(function(result) {
alert("Error: " + jqxhr.status + " " + jqxhr.statusCode() +" " + jqxhr.statusText);
})
.always(function(result) {
alert("Finished: " + result);
});
});
</script>
新控制器如下所示:
<?php
defined('_JEXEC') or die("Resricted Access!");
class PubControllerPubitems extends JControllerForm
{
public function RetrieveContent()
{
$app = JFactory::getApplication();
$post_data = $app->input->get('id');
// $post_data="This is a test";
echo($post_data);
}
}
?>
如果我没有注释掉$ post_data =“这是一个测试”行,我会从ajax调用返回'这是一个测试',一切都运行得很好。如果我发表评论,我什么都没得到,所以当从default.php模板发出或者在pubitems.raw.php控制器中的函数发出时,ajax调用仍然有问题。我仍然想弄明白,但欢迎任何额外的帮助。
答案 0 :(得分:0)
我终于通过持续的反复试验和大量使用Google来解决这个问题。
控制器如下所示:
<?php
defined('_JEXEC') or die("Resricted Access!");
class PubControllerPubitems extends JControllerForm
{
public function RetrieveContent()
{
$input = JFactory::getApplication()->input;
$cont_num = $input->get('pub_num', '', 'post');
$db = JFactory::getDBO();
$query = $db->getQuery(true);
$query->select('*');
$query->from('#__pub');
$query->where('pubid = ' . $pub_num);
$db->setQuery($query);
if ($db->getErrorNum()) {
$return_Data = $db->getErrorMsg();
$return_data = "Database Error";
}
else
{
$list = $db->loadObjectList();
foreach ($list as $item) {
pub_txt = $item->info;
$return_data = "Database Access Succeeded";
$return_data = $pub_txt;
}
}
echo($return_data);
}
}
?>
我现在已经发现,在Joomla 3.1中不推荐使用数据库错误的方式,它们应该作为例外处理,但是这个版本除此之外还可以正常工作。
我正在重复模板中的整个脚本部分,以便明确是否有其他人想要做同样的事情:
<script>
jQuery(".toc li").click(function(){
var data_to_send = {pub_num: this.id};
url = 'index.php?option=com_pub&controller=pubitems&task=pubitems.RetrieveContent&format=raw';
var jqxhr = jQuery.ajax(url,{
data: data_to_send
})
.done(function(result) {
alert("Success: " + jqxhr.status + " " + jqxhr.statusCode() + " " + jqxhr.statusText);
jQuery('#name-box').empty();
$pub_txt = jqxhr.responseText;
jQuery('#name-box').text($pub_txt);
})
.fail(function(result) {
alert("Error: " + jqxhr.status + " " + jqxhr.statusCode() +" " + jqxhr.statusText);
})
.always(function(result) {
alert("Finished: " + jqxhr.responseText);
});
});
</script>
我离开了警报,因为在我试图弄清楚发生了什么时,我发现这些非常有帮助。
我正在改变很多事情然后尝试一下,但最后我认为关键的事情是:
在调用RetrieveContent函数时,我包含了控制器的名称,因此它是task = pubitems.RetrieveContent。
我改变了编码数据的方式。这很难从我在网上找到的信息中找出来,最后我通过反复试验到达那里。
我停止尝试通过将数据包含在网址中来发送数据。相反,我将它单独包含在ajax调用'data:data_to_send'中。在我找到一种编码ajax调用数据的方法之前,我做到了这一点。
我希望这对别人有所帮助。我花了太长时间来解决这个问题,当然,现在我已经完成了它看起来很简单,但希望这会为其他人节省很多时间。
答案 1 :(得分:0)
您应该指明JInput请求的数据类型。
"marks": {
"Language 1 English": {
"Theory": ["ASL", "", "", "", ""],
"ASL": ["ASL", "", "", "", ""]
},
"Mathematics": {
"Theory": ["", "100", "33", "0", "Failed"]
},
"Physics": {
"Theory": ["Practical", "80", "27", "94", "Passed"],
"Practical": ["Practical", "", "", "", ""]
},
"Chemistry": {
"Theory": ["Practical", "", "", "", ""],
"Practical": ["Practical", "", "", "", ""]
},
"Biology/ Computer Science": {
"Theory": ["Practical", "100", "33", "30", "Failed"],
"Practical": ["Practical", "", "", "", ""]
}
}
永远不要相信输入,即使您使用CSRF令牌仍然需要强制输入类型。它现在可能不是必需的,但它的良好习惯(以及我的编码指南中的要求)。