4

我有一个 Ajax 请求,该请求将一些数据发送到一个页面,并根据数据是否被保存来期望返回一个真值或假值。在我的控制器中,我做所有事情并将内容设置为 true 或 false 值。我真的不想创建一个视图只是为了输出 1 个变量,所以我想知道是否有一种方法我不必使用视图而只使用控制器来输出简单的字符串。

4

3 回答 3

5

我相信您不能完全禁用视图,但有一个非常简单的解决方法:您可以创建一个视图并将其用于许多操作。

假设我们已经创建了 view 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();
}

希望这可以帮助。

于 2012-08-06T07:47:59.563 回答
2

你不能直接从控制器输出:它的工作只是调用模型并将数据传递给视图,所以你需要一个视图模板来进行输出。

但是,您可以避免使用框架的setView()方法为每个控制器方法创建单独的视图。这允许您覆盖约定并将单个视图应用于多个控制器方法。因此,您可以设置一个通用的“ajax 视图”,然后使用它从任何控制器输出数据:

意见/主要/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" );
}
于 2012-08-06T08:35:23.357 回答
1

您可以在 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 视图

于 2012-08-06T08:27:41.007 回答