2013-02-25 118 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); 
} 
相關問題