所以,我遇到了一个非常令人沮丧的问题。我正在进行AJAX调用(通过jquery.post()),该调用发送用于过滤Coldfusion对象的条件。
处理非常简单。首先,执行检查以查看是否已传入某些过滤器。如果存在过滤器,则会话范围中的对象循环通过,并且如果其中一个对象元素的值与过滤器列表中的任何项匹配值,该对象被添加到数组中。对所有已定义的过滤器类型完成此过程后,匹配对象的数组将存储在结果对象(obj.results)中,传递给serializeJSON函数,然后最终返回给客户端。
不幸的是,如果有多个过滤器正在运行,则看起来好像过早退出循环,导致返回的结果少于匹配。如果我只处理下面包含的两个过滤器中的一个,我会得到完整的预期结果。同样,如果在下面的每个arrayappend()调用中,我将s [i]更改为s [i] .name(因此,附加字符串而不是对象),将为每个过滤器返回预期的结果数。
这是使用s [i]的代码:
<cffunction name="filterObj" access="public" returntype="any">
<cfargument name="filterParams" type="struct" required="yes">
<cfset var s = session.a> <!--- session.a IS AN ARRAY OF CF OBJECTS --->
<cfset filteredResults = {}>
<cfset filteredResults.eligibilities = []>
<cfset filteredResults.agencies = []>
<cfif isdefined("arguments.filterParams.agency")>
<cfloop from="1" to="#arraylen(s)#" index="i">
<cfif structkeyexists(s[i],"agency") and
listfindnocase(arguments.filterParams["agency"],s[i].agency["name"])>
<cfset arrayappend(filteredResults.agencies, s[i])>
</cfif>
</cfloop>
</cfif>
<cfif isdefined("arguments.filterParams.eligibility")>
<cfloop from="1" to="#arraylen(s)#" index="i">
<cfif structkeyexists(s[i],"el")>
<cfloop from="1" to="#arraylen(s[i].eligibility)#" index="e">
<cfif listfindnocase(arguments.filterParams["eligibility"],s[i].eligibility[e].type)>
<cfset arrayappend(filteredResults.eligibilities, s[i])>
</cfif>
</cfloop>
</cfif>
</cfloop>
</cfif>
<cfset obj.results = filteredResults>
<cfset obj = serializeJSON(obj)>
<cfreturn obj>
</cffunction>
以下是使用s [i]
的未展开的console.logged结果RESULTS: Object
AGENCIES: Array[5]
ELIGIBILITIES: Array[5]
这是使用s [i] .name
的代码<cffunction name="filterObj" access="public" returntype="any">
<cfargument name="filterParams" type="struct" required="yes">
<cfset var s = session.a> <!--- session.a IS AN ARRAY OF CF OBJECTS --->
<cfset filteredResults = {}>
<cfset filteredResults.eligibilities = []>
<cfset filteredResults.agencies = []>
<cfif isdefined("arguments.filterParams.agency")>
<cfloop from="1" to="#arraylen(s)#" index="i">
<cfif structkeyexists(s[i],"agency") and
listfindnocase(arguments.filterParams["agency"],s[i].agency["name"])>
<cfset arrayappend(filteredResults.agencies, s[i].name)>
</cfif>
</cfloop>
</cfif>
<cfif isdefined("arguments.filterParams.eligibility")>
<cfloop from="1" to="#arraylen(s)#" index="i">
<cfif structkeyexists(s[i],"el")>
<cfloop from="1" to="#arraylen(s[i].eligibility)#" index="e">
<cfif listfindnocase(arguments.filterParams["eligibility"],s[i].eligibility[e].type)>
<cfset arrayappend(filteredResults.eligibilities, s[i].name)>
</cfif>
</cfloop>
</cfif>
</cfloop>
</cfif>
<cfset obj.results = filteredResults>
<cfset obj = serializeJSON(obj)>
<cfreturn obj>
</cffunction>
以下是使用s [i] .name
的未展开的console.logged结果RESULTS: Object
AGENCIES: Array[10]
ELIGIBILITIES: Array[6]
我觉得必须对服务器上发生的两个循环进行某种异步处理,或者在循环完成之前某些东西超时。
答案 0 :(得分:3)
在某些版本的CF9中存在已知问题,以及CF10,关于对象数组的序列化;通过将对象本身附加到return var而不是所述对象的基于字符串的键,你偶然发现了这个bug。
通过这个简单的脚本可以重现错误:
<cfset obj = ArrayNew(1) />
<cfset obj[1] = StructNew() />
<cfset obj[1].name = "Kate" />
<cfset obj[2] = StructNew() />
<cfset obj[2].name = "Ted" />
<cfset obj[3] = StructNew() />
<cfset obj[3].name = "Phil" />
<cfset data = ArrayNew(1) />
<cfloop from="1" to="#ArrayLen(obj)#" index="i">
<cfset ArrayAppend(data, obj[i]) />
</cfloop>
<cfdump var=#data#>
<cfloop from="1" to="#ArrayLen(obj)#" index="i">
<cfset ArrayAppend(data, obj[i]) />
</cfloop>
<cfdump var=#data#>
<cfoutput>#ArrayLen(data)#</cfoutput>
<cfset json = SerializeJSON(data) />
<cfdump var=#json#>
<cfset converted = DeserializeJSON(json) />
<cfoutput>#ArrayLen(converted)#</cfoutput>
预期的结果是最终的反序列化数组长度为6个元素,因为它是预序列化的。但是,实际结果是3。
坚持将字符串而不是整个对象附加到要返回的数组var中,如果绝对必须在从函数返回之前对其进行序列化,并重构调用此函数的异常代码。
消息来源:Problem with serializeJSON -- truncates embedded objects