0

Angularjs を使用してファイルマネージャーを作成しようとしていますが、最近 Breezejs を発見し、それを使用してバックエンドと通信し、モデルの関係を管理することに興味がありました。バックエンドは、私が完全に制御できる REST API です。

しかし、私は問題に直面しています。ファイルの ID はわかっているので、base64 でエンコードされたファイルの URL の形式backend_url/files/:fileIdのURL にリクエストを送信したいと思います。:fileIdドキュメントによると、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

少なくとも 1 つの問題は、"File" エンティティ タイプのメタデータ記述でキー ('id'?) を特定していないことです。「id」プロパティを除く他のすべてのプロパティを定義しました。

あなたはこれを知っていますが、サーバーからメタデータを取得するのではなく、JS クライアントでメタデータを定義していることを理解していない可能性があるこの質問の他の読者に伝えさせてください。

また、なぜ int16 を使用しているのか気になります。それは本当に正しいタイプですか?本当に 2 バイトを削る必要がありますか?

最後に、Breezeは "backend_url/files /:fetchEntityByKey fileId " の形式でリクエスト URL を作成しません。代わりに、要求 URL は、OData クエリに適した"backend_url/files /?id=: fileId " になります。DocCode サンプルの queryTests.cs で Id クエリのネットワーク トラフィックを参照してください。

サーバーが指定した URL を予期している場合は、そのファイルを取得できます。Breeze クエリ構文は使用しません。サービスが期待する URL でサービスをヒットするだけです。

関数 findOne(id) {
    // 最初にキャッシュをチェック
    var file = manager.getEntityByKey('File', id);
    if (ファイル) {
       console.log("キャッシュから取得しました");
       Q(ファイル)を返します。// とった; 解決された約束で戻る
    }
    // キャッシュにありません。サーバーから取得
    そよ風を返す.EntityQuery
        .from('Files/'+id) // 必要な URL を構築します
        .using(マネージャー).execute()
        .then(関数(データ){
            console.log("成功");}
            // 解決された promise でファイルを返します
            data.result[0] を返します || ヌル;
         }))
        .fail(関数(エラー){
            console.log("失敗: "+ error.message);
         });
}

これはgetByIdCacheOrRemote、DocCode サンプルの queryTest.cs のメソッドのバリエーションです。

はい、長くなりました。fetchEntityByKey期待どおりにリモート サービスをヒットできるように、再実装しています。

メソッドは、キャッシュ内のファイルを探すことから始まります。これgetEntityByKeyは、キャッシュの同期検索です。メソッドにはfindOne非同期構文があります... promiseを返します...サーバーに行く必要があるかもしれないからです。そのため、ファイルがキャッシュ内で (同期的に) 見つかった場合は、結果を解決済みの Q.js promise にラップして、findOne非同期であることを期待している呼び出し元に利益をもたらします。

ファイルがキャッシュに見つからない場合は、「クエリ」を使用してサーバーにアクセスします。これは、選択した URL に対する単なるリクエストです。

私はこれを長い間試していません。それが機能するかどうかは、あなたが教えてくれると思います...または機能しません。そうでない場合は、修正する必要があります。

于 2013-02-27T02:12:56.700 に答える
1

Wardが提案したように、私が作成したEnityTypeには、そのフィールドの1つをキーフィールドとしてマークする必要がありました。それに加えて、EntityTypeもdefaultResourceNameそのコンストラクターに提供される必要があります。これは、「通常の」クエリが機能した理由(resourceNameはによって提供されfrom()ます)とfe​​tchEntityByKeyが機能しなかった理由を説明していると思います。更新された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 に答える