2013-02-25 80 views
5

我试图用ColdFusion后端拾取AngularJS,并且遇到了一些障碍。我正在用CF Art Gallery数据库修改他们的“To Do”应用程序http://angularjs.org/。我正尝试使用AJAX将ColdFusion CFC链接到Angular应用程序。AngularJS和ColdFusion CFC

下面是我的artists.cfc:

<cfcomponent> 

<cffunction name="getArtists" access="remote" > 
    <cfargument name="firstName" default=""> 
    <cfargument name="lastName" default=""> 

    <cfquery name="getArtists_sql" datasource="cfartgallery"> 
     SELECT 
      firstname as text, 
      lastname as done 
     FROM artists 
     WHERE 0=0 
    <cfif firstName neq ""> 
     AND ucase(firstname) like ucase('%#FIRSTNAME#%') 
    </cfif> 
    <cfif lastName neq ""> 
     OR ucase(lastname) like ucase('%#LASTNAME#%')  
    </cfif> 
    </cfquery> 

    <cfreturn getArtists_sql> 
</cffunction> 

</cfcomponent> 

我打电话使用CFC AngularJS用下面的代码:

function TodoCtrl($scope, $http) { 
    $http.get('cfc/artists.cfc?method=getArtists&returnformat=json'). 
     success(function (response) { 
      $scope.todos = data.DATA; 
    }). 
     error(function (data) { 
      $scope.todos = data; 
     }); 
} 

我知道,我得到响应。下面是JSON字符串Chrome的开发者工具回报我:

{ 
"COLUMNS": 
    ["TEXT","DONE"], 
"DATA":[ 
    ["Aiden","Donolan"], 
    ["Austin","Weber"], 
    ["Elicia","Kim"], 
    ["Jeff","Baclawski"], 
    ["Lori","Johnson"], 
    ["Maxwell","Wilson"], 
    ["Paul","Trani"], 
    ["Raquel","Young"], 
    ["Viata","Trenton"], 
    ["Diane","Demo"], 
    ["Anthony","Kunovic"], 
    ["Ellery","Buntel"], 
    ["Emma","Buntel"], 
    ["Taylor Webb","Frazier"], 
    ["Mike","Nimer"] 
]} 

这看起来并不像他们的演示中使用的符号角:

[ 
{text:'learn angular', done:true}, 
{text:'build an angular app', done:false} 
] 

有人点我到正确的方向,以我如何才能让这个工作正常工作?理想情况下,我想保持CFC完好无损,以便可以重用于不同的应用程序,因此JSON操作必须在Javascript结束时完成。

+0

究竟是什么问题?顺便说一句,你的成功回调没有正确引用响应数据。它应该是'function(response){$ scope.todos = response.data.DATA; }'。 – Stewie 2013-02-25 18:29:20

+0

明确指出,我的问题是“我如何将来自AngularJS的TODO教程的信息替换为来自artist.cfc的信息?我尝试过'function(response){$ scope.todos = response.data.DATA;} '我得到一个'TypeError:无法读取属性'数据'的未定义' – Chester 2013-02-25 18:53:13

+0

我的坏,我误以'promise.then'显式'promise.success'方法(它提供数据和状态参数的回调)方法,该方法向具有data属性的响应对象提供回调,但在这种情况下,您的回调应该是'function(data){$ scope.todos = data.DATA;}'给定您的实际ajax响应body真的会返回您在答案中发布的JSON。 – Stewie 2013-02-25 19:13:15

回答

5

默认情况下,Coldfusion使用与您习惯的不同的JSON表示法。列名称存储在一个数组中,而数据存储在另一个数组中。我们实现的解决方案涉及将CFquery更改为数组。然后JSONEncoding该数组。

您将需要此功能在这里:

<cffunction name="QueryToArray" access="public" returntype="array" output="false"hint="This turns a query into an array of structures."> 
    <cfargument name="Data" type="query" required="yes" /> 

    <cfscript> 
     // Define the local scope. 
     var LOCAL = StructNew(); 

     // Get the column names as an array. 
     LOCAL.Columns = ListToArray(ARGUMENTS.Data.ColumnList); 

     // Create an array that will hold the query equivalent. 
     LOCAL.QueryArray = ArrayNew(1); 

     // Loop over the query. 
     for (LOCAL.RowIndex = 1 ; LOCAL.RowIndex LTE ARGUMENTS.Data.RecordCount ; LOCAL.RowIndex = (LOCAL.RowIndex + 1)){ 

     // Create a row structure. 
     LOCAL.Row = StructNew(); 

     // Loop over the columns in this row. 
     for (LOCAL.ColumnIndex = 1 ; LOCAL.ColumnIndex LTE ArrayLen(LOCAL.Columns) ; LOCAL.ColumnIndex = (LOCAL.ColumnIndex + 1)){ 

     // Get a reference to the query column. 
     LOCAL.ColumnName = LOCAL.Columns[ LOCAL.ColumnIndex ]; 

     // Store the query cell value into the struct by key. 
     LOCAL.Row[ LOCAL.ColumnName ] = ARGUMENTS.Data[ LOCAL.ColumnName ][ LOCAL.RowIndex ]; 

     } 

     // Add the structure to the query array. 
     ArrayAppend(LOCAL.QueryArray, LOCAL.Row); 

     } 

     // Return the array equivalent. 
     return(LOCAL.QueryArray); 

    </cfscript> 
</cffunction> 

然后你的回报将是这样的:

<cfreturn SerializeJson(QueryToArray(getArtists_SQL),true)> 

需要记住的是,一个CFQUERY对象包含其它属性,如总记录.. 。最有可能的是,JS只需要数据。我不知道是否有更优雅的解决方案,但是这是我们在遇到类似JQgrid问题时遇到的解决方案。

+0

嗯,这改变了从CFC到'{ “ROWCOUNT” JSON响应:15, “列”:[ “TEXT”, “DONE”], “DATA”:{ “TEXT”:[ “艾登”,“奥斯汀”, “Elicia”, “杰夫”, “洛瑞”, “麦斯威尔”, “禄”, “选秀”, “生活报”, “戴安娜”, “安东尼”, “埃勒里”, “爱玛”, “泰勒·韦伯” “迈克”], “DONE”: “Donolan”, “韦伯”, “金”, “Baclawski”, “强生”, “威尔逊”, “特拉尼”, “少年”, “特伦顿”, “演示” ,“Kunovic”,“Buntel”,“Buntel”,“Frazier”,“Nimer”]}}',但它仍然不像本教程中的数据。 – Chester 2013-02-25 18:55:22

+0

@Chester你是对的。我很抱歉。我会更新我的答案。 – 2013-02-25 19:23:51

+0

想过之后,我也得出了同样的结论,虽然方式不同。我真的想让CFC清理任何JSON修改,以便可以重新使用CFC,但我认为将来修改/添加任何CFC要比执行JavaScript更容易。话虽如此,我使用https://github.com/iknowkungfoo/ArrayCollection并将整个查询包装到它应该是的。谢谢你的帮助。现在我必须弄清楚如何让我的观点显示回应。 – Chester 2013-02-25 20:00:27

1

为了配合Blaise的上述答案。 我使用的queryToArray查看查询对象的columnList。 这是这样的列别名的情况下被保留。否则,它将在您的JSON中全部大写

/**queryToArray 
* utility method to keep the code dry. 
* @hint does exactly what the name says, take a query, makes it an array of stucts 
* @hint columnLabels pass in a list of columnLabels to just return those columns 
*/ 
public array function queryToArray(required query data, any columnLabels=false){ 
    var columns = listToArray(arguments.data.columnList); 
    if(arguments.columnLabels != false){ 
      columns = listToArray(arguments.columnLabels); 
    } 

    var queryArray = arrayNew(1); 

    for(i=1; i <= arguments.data.RecordCount; i++){ 

      row = StructNew(); 
      for (j=1; j <= ArrayLen(columns); j++){ 
       columnName = columns[j]; 
     row[columnName] = arguments.data[columnName][i]; 
      } 
      arrayAppend(queryArray, row); 
    } 
    return(queryArray); 
} 
相关问题