2013-02-25 73 views
0

我正在嘗試使用Angularjs創建一個文件管理器,最近我發現了Breezejs並試圖用它來與我的後端進行通信並管理我的模型關係。後端是我完全控制的其餘api。fetchEntityByKey沒有向服務器發送任何請求

但是我遇到了一個問題。我知道該文件的ID,所以我想請求backend_url/files/:fileId表單的url,其中:fileId是base64編碼文件的URL。根據文件,我應該使用EntityManager.fetchEntityByKey()來達到這個目的。這是我用於創建Angularjs服務功能:

var FilestoreService = function() { 

    var dataService, manager; 

    dataService = new breeze.DataService({ 
     serviceName: "../VFS-Symfony-Backend/web/app_dev.php/filesystems/local/", 

     hasServerMetadata: false 
    });   

    manager = new breeze.EntityManager({ 
     dataService: dataService 
    }); 

    manager.metadataStore.addEntityType(fileEntityType); 

    return { 
     findOneById: function (id) { 
      /* I have tried to leave the 3th argument empty or changing it to false with the same results */ 
      return manager.fetchEntityByKey("File", id, true).then(function(){console.log("success");}).fail(function(){console.log("failure");}); 

      /* I have also tried the following approach with the same result: 
      var type, key, query; 

      type = manager.metadataStore.getEntityType("File"); 
      key = new breeze.EntityKey(type, id); 
      query = breeze.EntityQuery.fromEntityKey(key); 

      return manager.executeQuery(query); 
      */ 
     } 
    }; 
}; 

其中fileEntityType定義爲:

var FileEntityType = new breeze.EntityType({ 
    shortName: "File" 
}); 

FileEntityType.addProperty(new breeze.DataProperty({ 
    name: "uri", 
    dataType: breeze.DataType.String, 
    isNullable: false 
})); 
FileEntityType.addProperty(new breeze.DataProperty({ 
    name: "mTime", 
    dataType: breeze.DataType.Int16, 
    isNullable: false 
})); 
FileEntityType.addProperty(new breeze.DataProperty({ 
    name: "type", 
    dataType: breeze.DataType.String, 
    isNullable: false 
})); 
FileEntityType.addProperty(new breeze.DataProperty({ 
    name: "size", 
    dataType: breeze.DataType.int16, 
    isNullable: true 
})); 

然而,當我打電話findOneById沒有請求向服務器發出和2線登錄到控制檯:

  • Should be empty:[]通過q.js

  • failure(按照fail()回調函數)

A '正常' 查詢(manager.executeQuery(new breeze.EntityQuery().from("Files"));)確實導致對服務器的請求按預期方式。

我真的很迷茫。我整個週末都在尋找解決方案,最終決定發佈SO,希望有人能夠幫助我。

非常感謝您的閱讀。

回答

1

隨着病房的建議,我創建的EnityType確實需要將其字段之一標記爲關鍵字段。除此之外,EntityType還需要有一個defaultResourceName提供給它的構造函數。我認爲這解釋了爲什麼「正常」查詢確實有效(resourceName由from()提供)以及爲什麼fetchEntityByKey不起作用。更新的FileEntityType現在看起來像這樣:

var FileEntityType = new breeze.EntityType({ 
    shortName: "File", 
    defaultResourceName: "files" 
}); 
FileEntityType.addProperty(new breeze.DataProperty({ 
    name: "id", 
    dataType: breeze.DataType.String, 
    isNullable: false, 
    isPartOfKey: true 
})); 

// These properties were not altered 
FileEntityType.addProperty(new breeze.DataProperty({ 
    name: "uri", 
    dataType: breeze.DataType.String, 
    isNullable: false 
})); 
FileEntityType.addProperty(new breeze.DataProperty({ 
    name: "mTime", 
    dataType: breeze.DataType.Int16, 
    isNullable: false 
})); 
FileEntityType.addProperty(new breeze.DataProperty({ 
    name: "type", 
    dataType: breeze.DataType.String, 
    isNullable: false 
})); 
FileEntityType.addProperty(new breeze.DataProperty({ 
    name: "size", 
    dataType: breeze.DataType.int16, 
    isNullable: true 
})); 
+0

很高興你知道這一點。如果此項目已關閉,請點擊左側的複選標記,以便我們可以將其關閉。感謝您使用Breeze。 – Ward 2013-02-27 22:03:42

+0

我認爲你應該給沃德修復的功勞。不是你自己。 – Chris 2014-03-09 23:57:07

+0

我非常感謝沃茲輸入,我同意他應得的所有功勞。我很好奇,儘管你會建議我這樣做。在我的回答開始時,我確實提到了沃德,並且我確實讚揚了他的回答。你是否建議我應該接受Wards的回答,即使這最終不是我的理想解決方案?或者我應該在這個答案中增加一個更加明確的信貸病房?歡迎提出建議。 – Roland 2014-03-10 20:00:25

4

至少有一個問題是您尚未在您的元數據描述的「文件」實體類型中標識關鍵字('id'?)。您已定義'id'屬性外的所有其他財產。

你知道這一點,但讓我告訴這個問題的其他讀者誰可能不明白,你是定義在JS客戶端的元數據,而不是從服務器檢索它。

我也很好奇你爲什麼使用int16?這真的是正確的類型嗎?你真的需要削減兩個字節嗎?

最後,Breeze的fetchEntityByKey將不會以「backend_url/files /:fileId」的形式發出請求URL。相反,請求URL將是「backend_url/files /?id =:fileId」,因爲它適合OData查詢。查看DocCode示例的queryTests.cs中Id查詢的網絡流量。

如果服務器期望您指定的URL,您仍然可以獲取該文件。你將不會使用Breeze查詢語法。您只需打服務與預計的URL,例如,

 
function findOne(id) { 
    // check cache first 
    var file = manager.getEntityByKey('File', id); 
    if (file) { 
     console.log("got it from cache"); 
     return Q(file); // got it; return in resolved promise 
    } 
    // not in cache; get from server 
    return breeze.EntityQuery 
     .from('Files/'+id) // constructs the URL you want 
     .using(manager).execute() 
     .then(function(data){ 
      console.log("success");} 
      // return the file in a resolved promise 
      return data.results[0] || null; 
     }) 
     .fail(function(error){ 
      console.log("failure: "+ error.message); 
     }); 
} 

這是在DocCode樣品中queryTest.cs的getByIdCacheOrRemote方法的變化。

是的,它更長。您正在重新實現fetchEntityByKey,因此您可以按照預期的方式點擊遠程服務。

該方法首先查找緩存中的文件。 getEntityByKey是緩存的同步搜索。 findOne方法有異步語法...返回一個承諾...因爲它可能可能必須去服務器。因此,如果我們在緩存中找到文件(同步),我們會將結果包裝在一個已解析的Q.js承諾中,以期望findOne爲異步的調用方。

如果在緩存中未找到該文件,則用「查詢」即轉到服務器,該服務實際上只是您選擇的URL的請求

我還沒有試過這麼長時間。我相信你會告訴我它是否有效,或者沒有。如果沒有,它應該,我們會解決它,所以它。

+0

您的解決方案創建url我的後端預計確實工作。但是,由於我已經控制了後端API,因此我決定擴展後端以與odata請求兼容,因爲這感覺就像是正確的解決方案。我曾嘗試將屬性標記爲密鑰的一部分,但沒有得到任何不同的結果,並刪除了此代碼,因爲我假定可以自動生成關鍵字段。我沒有意識到失敗回調會收到一個錯誤對象,這幫助我追蹤了這個問題:需要提供給EnityType的'defaultResourceName'屬性。 – Roland 2013-02-27 17:31:56

相關問題