我有一个Ajax请求,它向页面发送一些数据,并根据数据是否保存而返回truthy或false值。在我的控制器中,我做所有事情,并将内容设置为真值或假值。我真的不想只创建一个视图来输出1个变量,所以我想知道是否有一种方法可以让我不必使用视图,只使用控制器来输出简单的字符串。
我相信您不能完全禁用视图,但有一个非常简单的解决方法:您可以创建一个视图并将其用于多个操作。
假设我们已经创建了视图views/main/ajax.cfm
,它里面可能有什么?显然,最简单的方法是:
<cfoutput>#HTMLEditFormat(rc.response)#</cfoutput>
就我个人而言,我喜欢返回JSON,如果需要的话,它允许我有status
字段和数据。我的观点是这样的:
<cfheader name="Content-Type" value="application/json" />
<cfoutput>#SerializeJSON(rc.response)#</cfoutput>
无论如何,现在在我们的行动中,我们需要做这样的事情:
// prevent displaying the layout
request.layout = false;
// force special view
variables.fw.setView("main.ajax");
// init response (according to the choice made earlier)
rc.response["status"] = "OK";
rc.response = "";
还有一个问题。有时你不想直接访问AJAX页面(比如在浏览器中打开),反之亦然——当它被打开时,你想做一些调试。
CFWheels框架中有一个很酷的助手isAjax
,它很容易移植到FW/1。它可以像在控制器中添加这样的方法一样简单:
/*
* Check if request is performed via AJAX
*/
private boolean function isAjax() {
return (cgi.HTTP_X_REQUESTED_WITH EQ "XMLHTTPRequest");
}
事实上,上面的设置代码也是我的应用程序中的辅助方法:
/*
* Set up for AJAX response
*/
private struct function setAjax() {
// prevent displaying the layout
request.layout = false;
// force special view
variables.fw.setView("main.ajax");
local.response["status"] = "OK";
return local.response;
}
所以在我的操作代码中,整个检查看起来像这样,非常紧凑和方便:
if (isAjax()) {
rc.response = setAjax();
}
else {
return showNotFound();
}
希望这能有所帮助。
您不能直接从控制器输出:它的工作只是调用Model并将数据传递给View,因此您需要一个视图模板来进行输出。
但是,通过使用框架的setView()方法,可以避免为每个控制器方法创建单独的视图。这允许您覆盖约定,并将单个视图应用于多个控制器方法。因此,您可以设置一个通用的"ajax视图",然后使用它从任何控制器输出数据:
views/main/ajax.cfm
<!---Prevent any layouts from being applied--->
<cfset request.layout=false>
<!--- Minimise white space by resetting the output buffer and only returning the following cfoutput --->
<cfcontent type="text/html; charset=utf-8" reset="yes"><cfoutput>#rc.result#</cfoutput>
控制器.cfc
function init( fw )
{
variables.fw=arguments.fw;
return this;
}
function getAjaxResponse( rc )
{
rc.result=1;
fw.setView( "main.ajax" );
}
function getAnotherAjaxResponse( rc )
{
rc.result=0;
fw.setView( "main.ajax" );
}
您可以在Application.cfc中使用onMissingView来处理ajax调用的响应,这样您就不需要在控制器方法中执行任何额外的逻辑。
// Application.cfc
function onMissingView(rc) {
if(structKeyExists(rc, "ajaxdata") && isAjaxRequest()) {
request.layout = false;
content type="application/json";
return serializeJSON(rc.ajaxdata);
}
else {
return view("main/notfound");
}
}
function isAjaxRequest() {
var headers = getHttpRequestData().headers;
return structKeyExists(headers, "X-Requested-With")
&& (headers["X-Requested-With"] eq "XMLHttpRequest");
}
// controller cfc
function dosomething(rc) {
rc.ajaxdata = getSomeService().doSomething();
}
这会检查请求上下文是否有ajaxdata键,并且是真正的ajax请求,然后返回序列化数据。如果没有,则渲染main.notfound视图