0

Durandal SPA プロジェクトで Breeze を使用しています。

検索結果ページに要素のリストがあります。ユーザーが 1 つの要素をクリックするたびに、そのアイテムが他のユーザーによってロックされていないことを確認するためにサーバーにクエリを実行します。この場合、モーダル ダイアログを表示して、現在誰がアイテムをロックしているかをユーザーに警告します。

以下の最初のシナリオではうまく機能します。

シナリオ 1:

  • t: 要素 E はロックされていません。
  • t+1: 検索結果ページで要素 E がクリックされた
  • t+2: サーバーに問い合わせて、この要素のロックを確認します (結果: ロックされていません)
  • t+3: 要素 E の詳細ページを表示します

シナリオ 2:

  • t: 要素 E はロックされていません。
  • t+1: 検索結果ページで要素 E がクリックされた
  • t+2: サーバーに問い合わせて、この要素のロックを確認します (結果: John によってロックされました)
  • t+3: モーダル ポップアップを表示して、John が要素をロックしたことをユーザーに警告します
  • t+4: ジョンが要素 E を解放した
  • t+5: 検索結果ページで要素 E が再度クリックされた
  • t+6: サーバーに問い合わせて、この要素のロックを確認します (結果: ポールによってロックされました)
  • t+7: モーダル ポップアップを表示して、Paul が要素をロックしたことをユーザーに警告します。
  • t+8: ポールがエレメント E をリリース

(したがって、現時点では誰も要素をロックしていません --> LockedBy は null である必要があります)

  • t+9: 検索結果ページで要素 E が再度クリックされた
  • t+10: サーバーに問い合わせて、この要素のロックをチェックします (結果: Paul によってロックされました) <- !!!!

ご覧のとおり、問題は 2 番目のシナリオのステップ 10 で発生します。値が null (LockedBy) のときはいつでも、そよ風はまだこのプロパティに古い値を使用しているようです?!

何か案が?

以下は、Breeze でサーバーにクエリを実行するための私のコードです。

var getTransportById = function (transportId, transportObservable) {
    // Input: transportId: the id of the transport to retrieve
    // Output: transportObservable: an observable filled with the transport

    var query = entityQuery.from('Transports')
        .where('id', '==', transportId)
        .expand("Sender.City, Sender.City.Country, Receiver.City, Receiver.City.Country, Insurances, Client.City, Client.City.Country, LockedBy");

    query = query.using(breeze.FetchStrategy.FromServer);

    return manager.executeQuery(query)
        .then(querySucceeded)
        .fail(queryFailed);

    function querySucceeded(data) {
        transportObservable(data.results[0]);
    }
};

以下は私のモデルの一部です:

public class Transport
{
    [Key]
    public int Id { get; set; }
    public string TransportNumber { get; set; }
    public string Remark { get; set; }

    public int? LockedById { get; set; }
    public DateTime? LockedTime { get; set; }

    public virtual User LockedBy { get; set; }
}

PS: ブラウザーでトラフィック データを分析すると、Breeze はナビゲーション プロパティが null の場合、データを送信しなかったようです。したがって、私のシナリオでは、他の誰か (別のセッションの別のユーザー) がこのデータを変更したため、クライアント キャッシュの値が正しくなくなり、Breeze が null 値でプロパティを送信しなかったため、クライアント キャッシュが正しく更新されませんでした。私がはっきりしていることを願っています。

4

1 に答える 1

1

私は理論を持っていると思います。デフォルトでは、Breeze Web API コントローラーの JSON.Net シリアライザーは nullを返しません

クエリからデータが到着すると、Breeze は受け取った値を既存のエンティティにマージします... プロパティごとに。問題が見えますか?フォローしてください:

  1. id=1 で Foo をクエリします

  2. 受信した JSON は{id: 1, name: "Foo"}で、Breeze は実体化された Foo エンティティの対応するプロパティを設定します

  3. サーバー上の何かが名前を「Bar」に変更します。あなたは再質問します

  4. 受信した JSON は{id: 1, name: "Bar"}です。Foo エンティティは {id:1, name: "Bar"} になりました

  5. サーバー上の何かが名前をnullに変更します。あなたは再質問します

  6. 受信した JSON は{id: 1}です プロパティ の値がありませんname!!!

  7. Breeze は値をマージします。ただし、マージする値がないnameため、もちろんname以前の値を保持します。

  8. Foo エンティティは {id:1, name: "Bar"} のままですが、サーバーの同等物は {id:1, name: null} です

私が考えることができる 1 つの回避策は、JsonFormatter を再構成して null 値を送信することです。もう 1 つの方法は、この特定のユース ケースに合わせてカスタム JsonResultsAdapterを作成することです。不足しているプロパティ (例: name) を検出し、それらをノードに追加します。この場合は null 値を使用します。

このシナリオは、デフォルトで null 値を抑制するという私たちの決定の賢明さに疑問を抱かせます。私はこれをチームに持ち出します。

于 2013-06-08T06:37:11.827 に答える