0

我正在尝试使用 Angularjs 创建一个文件管理器,我最近发现了 Breezejs,并有兴趣尝试使用它与我的后端通信并管理我的模型关系。后端是一个我可以完全控制的 rest api。

然而,我遇到了一个问题。我知道文件的 id,所以我想向格式的 url 发出请求,backend_url/files/:fileId其中:fileId文件的 url 是 base64 编码的。根据我应该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()回调函数)

“正常”查询 ( manager.executeQuery(new breeze.EntityQuery().from("Files"));) 确实会按预期向服务器发出请求。

我真的很迷失在这里。我整个周末都在寻找解决方案,最后决定在 SO 上发帖,希望有人能帮助我。

非常感谢您的阅读。

4

2 回答 2

4

至少有一个问题是您没有在“文件”实体类型的元数据描述中确定键('id'?)。您已经定义了除“id”属性之外的所有其他属性。

您知道这一点,但让我告诉这个问题的其他读者,他们可能不明白您是在 JS 客户端上定义元数据,而不是从服务器检索元数据。

我也很好奇你为什么使用int16?这真的是正确的类型吗?你真的需要剃掉这两个字节吗?

最后,BreezefetchEntityByKey不会以“backend_url/files /:fileId ”的形式发出请求 URL。相反,请求 URL 将是“backend_url/files /?id=:fileId ”,以适合 OData 查询。在 DocCode 示例的 queryTests.cs 中查看 Id 查询的网络流量。

如果服务器需要您指定的 URL,您仍然可以获取该文件。您不会使用 Breeze 查询语法。您只需使用它期望的 URL 访问服务,例如,

函数 findOne(id) {
    // 先检查缓存
    var file = manager.getEntityByKey('File', id);
    如果(文件){
       console.log("从缓存中获取");
       返回Q(文件);// 知道了; 返回已解决的承诺
    }
    // 不在缓存中;从服务器获取
    返回微风.EntityQuery
        .from('Files/'+id) // 构造你想要的 URL
        .using(manager).execute()
        .then(函数(数据){
            console.log("成功");}
            // 在已解决的承诺中返回文件
            返回数据.结果[0] || 空值;
         })
        .失败(功能(错误){
            console.log("失败:"+ error.message);
         });
}

这是getByIdCacheOrRemoteDocCode 示例中 queryTest.cs 中方法的变体。

是的,它更长。您正在重新实现fetchEntityByKey,因此您可以按预期方式访问远程服务。

该方法首先在缓存中查找文件。这getEntityByKey是缓存的同步搜索。该findOne方法具有异步语法...返回一个承诺...因为它可能必须转到服务器。因此,如果我们在缓存中找到文件(同步),我们将结果包装在一个已解析的 Q.js 承诺中,以使调用者受益,该调用者期望findOne是异步的。

如果在缓存中未找到该文件,您将使用“查询”转到服务器,该“查询”实际上只是对您选择的 URL 的请求

我很久没试过这个了。我相信你会告诉我它是否有效......或无效。如果没有,它应该这样做,我们会修复它。

于 2013-02-27T02:12:56.700 回答
1

正如 Ward 建议的那样,我创建的 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
}));
于 2013-02-27T17:42:34.243 回答