0

複雑な型をそよ風に遅延ロードしようとしていますが、これを達成する方法がわかりません。

ナビゲーションの方法ではなく複雑なタイプを使用したい理由は、私が消費しなければならないサービスが、ブリーズと同じ方法で CRUD を実行していないからです。すべてのサブオブジェクト (スカラーと非スカラーの両方) を含む 1 つのオブジェクトを、データの格納 (挿入/更新/削除) を担当する 1 つのサービス メソッドに送信する必要があります。

ナビゲーション プロパティを使用してこれを実行しようとしましたが、これはエンティティの配列を作成して API コントローラーに送信し、そこでオブジェクト全体を再作成する必要があることを意味します。これは困難ですが、子オブジェクトには外部キーがないため (これまでに見たすべてのサンプルに当てはまります)、それらを再度マップするのが面倒です。

複雑な型では、この問題はありません (または、私が認識していません)。

次のようなオブジェクト構造を使用する必要があります。

1.親: 製品 (クラス)

1.1Child: パッケージ (配列)

1.2Child: splitLevels (配列)

1.2.1Grandchild: パーミッション (配列)

1.2.1.1孫:薬局(配列)

1.2.2Grandchild: splitLevel (クラス)

パッケージは製品と一緒にロードされます。これは問題なく機能します。ただし、splitLevels はこの datacontract には含まれていません (必要なデータが多すぎて、それほど頻繁には参照されないため)。このデータを要求すると、ブール値が製品に追加されてロードされたことを示します。それ以降は、サーバーにもデータを送信する必要があります。

製品をロードするとき、これにより問題が発生します: オブジェクトはプロパティまたはメソッド 'getProperty' をサポートしていません

これは、breeze の _initializeInstance メソッドが原因です。

if (initFn) {
    if (typeof initFn === "string") {
        initFn = instance[initFn];
    }
    initFn(instance);
}
this.complexProperties && this.complexProperties.forEach(function (cp) {
    var ctInstance = instance.getProperty(cp.name);
    cp.dataType._initializeInstance(ctInstance);
});

インスタンスが空です。そこからプロパティを取得できません。

これを回避する方法はありますか? 複数のエンティティを取得せずにナビゲーション プロパティを使用する方法はありますか。したがって、これを使用せずに単一のオブジェクトを送信できます。

if (product.entityAspect.entityState.isUnchanged()) {
    product.entityAspect.setModified();
}

// Packages
var entitiesToSave = product.packages().slice();// copy

// Split Levels
if (product.storeSplitLevels) {
    product.splitLevelsLoaded(true);
    // TODO: Add split levels to entities to save
}

// Product Details
entitiesToSave.push(product);
4

2 に答える 2

1

あなたの提案に従って、カスタム バンドルを作成しました。

同じ問題を抱えている他の開発者のために、私は次のことを行いました。

  1. ブリーズのアンラップ関数と同じ機能を提供するカスタム アンラップ関数を作成しますが、ナビゲーション プロパティも含めるように拡張します。

  2. エンティティから保存バンドルを作成するメソッドを追加します。

コード:

function createEntitySaveBundle(entity) {
    var rawEntity = unwrapInstance(entity);
    var entities = [];
    rawEntity.entityAspect = {
        entityTypeName: entity.entityType.name,
        defaultResourceName: entity.entityType.defaultResourceName,
        entityState: entity.entityAspect.entityState.name,
        autoGeneratedKey: {
            propertyName: entity.entityType.keyProperties[0].nameOnServer,
            autoGeneratedKeyType: entity.entityType.autoGeneratedKeyType.name
        }
    };
    entities.push(rawEntity);

    return { entities: entities, saveOptions: {} };
}

function unwrapInstance(entity) {
    var rawObject = {};
    var stype = entity.entityType || entity.complexType;
    var val;
    var entities;

    stype.dataProperties.forEach(function (dp) {
        if (dp.isUnmapped) {
            val = entity.getProperty(dp.name);
            val = transformValue(val, dp, false);
            if (val !== undefined) {
                rawObject.__unmapped = rawObject.__unmapped || {};
                // no name on server for unmapped props
                rawObject.__unmapped[dp.name] = val;
            }
        } else if (dp.isComplexProperty) {
            if (dp.isScalar) {
                rawObject[dp.nameOnServer] = unwrapInstance(entity.getProperty(dp.name));
            } else {
                entities = entity.getProperty(dp.name);
                rawObject[dp.nameOnServer] = entities.map(function (co) { return unwrapInstance(co); });
            }
        } else if (dp.isDataProperty) {
            val = entity.getProperty(dp.name);
            val = transformValue(val, dp);
            if (val !== undefined) {
                rawObject[dp.nameOnServer] = val;
            }
        }
    });

    stype.navigationProperties.forEach(function (np) {
        if (np.isScalar) {
            // Doesn't occur with products, enabling this results in an endless loop without checking if the navigation property already exists in the rawObject (recursive..)
            // rawObject[np.nameOnServer] = unwrapInstance(entity.getProperty(np.name));
        } else {
            entities = entity.getProperty(np.name);
            rawObject[np.nameOnServer] = entities.map(function (eo) { return unwrapInstance(eo); });
        }
    });

    return rawObject;
}
function transformValue(val, prop) {
    if (prop.isUnmapped) return;
    if (prop.dataType === breeze.DataType.DateTimeOffset) {
        // The datajs lib tries to treat client dateTimes that are defined as DateTimeOffset on the server differently
        // from other dateTimes. This fix compensates before the save.
        val = val && new Date(val.getTime() - (val.getTimezoneOffset() * 60000));
    } else if (prop.dataType.quoteJsonOData) {
        val = val != null ? val.toString() : val;
    }
    return val;
}
于 2013-10-22T09:35:16.547 に答える
0

詳細情報がなければ、あなたが何を求めているのか完全にはわかりませんが、任意のデータ構造を持つ任意のエンドポイントを呼び出し、呼び出しの結果を取得できるようにする関数を EntityManager の Breeze API に追加することを計画しています。があれば、JsonResultsAdapter を介して EntityManager にマージされます。

それまでは、EntityManager.saveChanges をバイパスし、Breeze ajax アダプターを直接使用してエンドポイントを呼び出すだけで、今すぐこれの一部を実現できます。何かのようなもの

var ajaxImpl = breeze.config.getAdapterInstance("ajax");
ajaxImpl.ajax({
        type: "POST",
        url: url,
        dataType: 'json',
        contentType: "application/json",
        data: bundle,   // arbitrary data to server.
        success: function (httpResponse) {
            // perform custom client side code 
        },
        error: function (httpResponse) {

        }
    });
于 2013-10-09T17:20:43.233 に答える