4

私のWebアプリでは、次のようなAPIへのAJAX呼び出しから3〜4秒ごとにデータを受信して​​います:

$http.get('api/invoice/collecting').success(function(data) {
    $scope.invoices = data
}

次に、次のようにデータを表示します: http://jsfiddle.net/geUe2/1/

問題は、$scope.invoices = datang-repeat を実行するたびに、jsfiddle に表示される DOM 領域を再構築し、すべての<input>値を失うことです。

私はやろうとしました:

  • angular.extend()
  • のディープバージョンjQuery.extend
  • その他のマージ\拡張\ディープ コピー機能

しかし、彼らは次のような状況を処理できません。

私のクライアントでは、持っている[invoice1, invoice2, invoice3]サーバーが私に送信します[invoice1, invoice3]。したがって、invoice2 をビューから削除する必要があります。

この問題を解決する方法は何ですか?

4

3 に答える 3

1

ng-repeatドキュメントAngular.js - Data from AJAX request as a ng-repeat collectionオプション を使用track byできます:

variable in expression track by tracking_expression – コレクション内のオブジェクトを DOM 要素に関連付けるために使用できるオプションの追跡関数を提供することもできます。追跡機能が指定されていない場合、ng-repeat はコレクション内の ID によって要素を関連付けます。複数のトラッキング関数を同じキーに解決するのはエラーです。(これは、2 つの異なるオブジェクトが同じ DOM 要素にマップされることを意味しますが、これは不可能です。) 追跡式を指定する前に、フィルターを式に適用する必要があります。

例: item.id によるアイテム トラック内のアイテムは、アイテムがデータベースから取得される場合の典型的なパターンです。この場合、オブジェクト ID は重要ではありません。id プロパティが同じである限り、2 つのオブジェクトは同等と見なされます。

于 2013-08-30T14:06:52.963 に答える
0

サーバーからの更新が到着したときに、DOM からデータを収集する必要があります。関連するすべてのデータを保存し (入力値のみの場合もあります)、データ オブジェクトの識別子 ( など) を含めることを忘れないでくださいdata._id。これらはすべて、 などの一時オブジェクトに保存する必要があります$scope.oldInvoices

次に、DOM から収集した後、新しいデータで DOM を再更新します (現在行っている方法) $scope.invoices = data。ここで、underscore.js _.findWhereを使用して、data._id が新しいデータ更新に存在するかどうかを確認し、存在する場合は、関連する請求書Angular.extendに保存したデータ値を再割り当て (ここで使用できます) します。

于 2013-08-30T13:55:50.407 に答える
0

track byディレクティブのオプションに関する@luacassusの回答ng-repeatは非常に役に立ちましたが、私の問題は解決しませんでした。track by機能はサーバーからの新しい請求書を追加していましたが、非アクティブな請求書の消去で問題が発生しました。だから、これは問題の私の解決策です:

function change(scope, newData) {
    if (!scope.invoices) {
        scope.invoices = [];
        jQuery.extend(true, scope.invoices, newData)
    }
    // Search and update from server invoices that are presented in scope.invoices
    for( var i = 0; i < scope.invoices.length; i++){
        var isInvoiceFound = false;
        for( var j = 0; j < newData.length; j++) {
            if( scope.invoices[i] && scope.invoices[i].id && scope.invoices[i].id == newData[j].id ) {
                isInvoiceFound = true;
                jQuery.extend(true, scope.invoices[i], newData[j])
            }
        }
        if( !isInvoiceFound ) scope.invoices.splice(i, 1);
    }
    // Search and add invoices that came form server, but are nor presented in scope.invoices
    for( var j = 0; j <  newData.length; j++){
        var isInvoiceFound = false;
        for( var i = 0; i < scope.invoices.length; i++) {
            if( scope.invoices[i] && scope.invoices[i].id && scope.invoices[i].id == newData[j].id ) {
                isInvoiceFound = true;
            }
        }
        if( !isInvoiceFound ) scope.invoices.push(newData[j]);
    }

}

私の Web アプリでは、jQuery の.extend(). lo-dashライブラリには、いくつかの優れた代替手段があります。

于 2013-10-19T06:45:06.603 に答える