使用CF 10.为了在不刷新整个页面的情况下重新填充选择,我在更改select时执行远程cfc调用,该调用运行查询并以JSON格式返回。在我的$ .post()回调中,我接受这个JSON文本并立即使用JSON.parse()将其转换为JS对象。所以我现在有一个包含2个数组的JS对象:COLUMNS,它是所有列名的数组,DATA是数组的数组,每个数组代表查询中的一行。因此查询中的每个字段都是DATA [rownumber] [columnnumber]。
我想弄清楚的是处理这个JS对象最优雅的方法。我可以很容易地用$ .each()迭代它并填充select的选项,但是如果我想在一列或多列上对结果集进行排序呢?或者按列名称引用字段?我想知道在返回qry之前我是否最好不要在cfc中做一些事情,比如将它转换为结构。以下是我的cfc功能代码:
<cffunction name="getStaffRemote" access="remote" returntype="query" returnformat="JSON" output="false">
<cfargument name="iEmpId" type="any" required="false" />
<cfset var qry= "" />
<cfquery name="qry" datasource="#this.DSN#">
SELECT iEmpid, vEmpLname, vEmpFname, isActive
FROM tEmployees
where 1=1
<cfif isDefined("arguments.iEmpId") AND isNumeric(arguments.iEmpId) AND arguments.iEmpId GT 0>
AND iEmpId = <cfqueryparam cfsqltype="cf_sql_integer" value="#arguments.iEmpId#" />
</cfif>
</cfquery>
<cfreturn qry />
</cffunction>
感谢您的想法。顺便说一句,我也想知道为什么查询接受this.DSN,它只是application.dsn的副本。我认为当一个函数被远程直接调用时,应用范围变量是不可用的,即&#34; $。post(&#39; myCFC.cfc?method = getStaffRemote&amp ;. ..&#39;&#34;
(回复回答):
非常好 - 谢谢!对于更大的查询,我会记住这一点。在这种情况下,我最终使用返回的JSON和jQuery一样 - 这很简单,因为只有几列:
$.get("cfc/employees.cfc?method=getStaffRemote&vActive=" + vActive,
function(jsonText){
var qryStaff = JSON.parse(jsonText);
//qryStaff is now an object with 2 arrays: COLUMNS and DATA.
//COLUMNS is an array of strings of the column names.
//DATA is an array of arrays, where each array is a row.
//Thus, every data cell is DATA[rownumber][columnnumber]
//[0] = iEmpId
//[1] = vEmpLName
//[2] = vEmpFName
//[3] = isActive
$('#iEmpID_Staff').empty();
$.each(qryStaff.DATA, function() {
$('#iEmpID_Staff').append('<option value=' + $(this)[0] + '>' + $(this)[1] + ', ' + $(this)[2] + '</option>');
});
}
);
答案 0 :(得分:1)
ColdFusion在序列化查询对象时产生的JSON不是最好的工作方式。我经常做的是将查询转换为结构数组并返回它。你最终会得到一个更大的JSON有效负载,因为列名会被重复,但是如果你启用了gzip会有所帮助,但你需要考虑你有多少数据以及这是否是一个很好的解决方案,但是值得考虑,所以你的前端开发人员以理智的形式获得JSON:)
这样的事情应该这样做:
<cffunction name="getStaffRemote" access="remote" returntype="query" returnformat="JSON" output="false">
<cfargument name="iEmpId" type="any" required="false" />
<cfset var qry= "" />
<cfquery name="qry" datasource="#this.DSN#">
SELECT iEmpid, vEmpLname, vEmpFname, isActive
FROM tEmployees
where 1=1
<cfif StructKeyExists(arguments, "iEmpId") AND isNumeric(arguments.iEmpId) AND arguments.iEmpId GT 0>
AND iEmpId = <cfqueryparam cfsqltype="cf_sql_integer" value="#arguments.iEmpId#" />
</cfif>
</cfquery>
<cfscript>
var result = [];
for (var row in qry) {
arrayAppend(result, row);
}
return result;
</cfscript>
</cffunction>
那将返回看起来像这样的JSON:
[
{"IEMPID":1, "VEMPLNAME":"Bloggs", "VEMPFNAME":"Jo", "ISACTIVE": true},
{"IEMPID":2, "VEMPLNAME":"Smith", "VEMPFNAME":"Sam", "ISACTIVE": true}
]
现在,JS中的排序变得更加简单:
myArray.sort(function(a, b) {
return something; // do your compare here
});
您也可以将要排序的列作为第二个参数传递给getStaffRemote
方法,并添加一个或子句。如果你走这条路,你还需要保护它免受SQL注入攻击。