1

Angular の重要な原則の 1 つは次のとおりであることを理解しています。

あなたのコントローラー内からあなたの DOM を参照してはいけません。

クレジット カードによる支払いを処理しようとしていますが、次の手順が必要です。

  • ユーザーがフォームに入力し、送信ボタンをクリックする
  • そのフォームの一部がサーバーに送信され、支払いゲートウェイとの取引が開始されます
  • サーバーからの応答によってフォームの値が更新されます。この値は、フォーム POST を介して支払いゲートウェイに直接送信する必要があります。
  • 他のことが起こります。

このシナリオでは、次のことを行うにはどうすればよいですか。

  • フォーム内のデータを更新します (コントローラーからフォームを参照せずに)
  • 送信するフォームを取得しますか?

フォームはコントローラーのモデルにバインドされるため、次のようなことを試しました。

<form action="{{paymentModel.urlFromTheResponse}}">
    <input type="hidden" name="accessCode" value="{{paymentModelaccessCodeFromResponse}}" />
    <button ng-click="startTransaction(paymentModel)"></button>
</form>

// in my success handler
.success(function(data) {
     paymentModel.urlFromTheResponse = data.url;
     paymentModel.accessCode = data.accessCode;
     $scope.apply();
}

ここにある理論は、データバインディングを介してフォームをすぐに正しい状態にすることができれば、フォームを送信するために何かを行うことができるということです。ただし、これはエラーをスローします。

ダイジェストが進行中

このタイプのフローをサポートする Angular の方法は何ですか? コントローラの性質に反する DOM と直接対話する必要があるようです。

4

3 に答える 3

1

他の人が述べているように、 $scope.$apply() を呼び出す必要はありません。これは、各フィールドに ng-model 属性を設定することにより、フォームが既に angular に関連付けられている必要があるためです。

ただし、角度の外部の他のソースからデータが取り込まれたときに、表示を更新するために $scope.$apply() を呼び出す必要がある場合があります...

そのような場合、私はこれでとても幸運でした:

  // This method will be inherited by all other controllers
  // It should be used any time that $scope.$apply() would
  // otherwise be used.
  $scope.safeApply = function(fn) {
    var phase = this.$root.$$phase;
    if(phase == '$apply' || phase == '$digest') {
      if(fn && (typeof(fn) === 'function')) {
        fn();
      }
    } else {
      this.$apply(fn);
    }
  };

私はそれを一番外側のコントローラーに配置するので、ページ上の他のすべてのコントローラーはそこから関数を継承します。適用する呼び出しが必要な場合はいつでも、代わりに $scope.safeApply() を呼び出します。すでに適用またはダイジェストが進行中です。それ以外の場合、これらの変更は、現在実行中の適用/ダイジェストによってすでに取得されています。

あなたのコードでは、これを変更します:

<input type="hidden" name="accessCode" value="{{paymentModelaccessCodeFromResponse}}" />

これに:

<input type="hidden" name="accessCode" ng-model="paymentModel.accessCode" />

おそらくフォームアクションも削除し、代わりにコントローラーに次のようなものを追加します。

$scope.$watch('paymentModel.accessCode', function() {
  // Fire off additional form submission here.
})
于 2013-01-28T19:57:45.307 に答える
0

成功のコールバックが既に「Angular 内」にあるため、エラーが生成されるため、 $scope.apply() が自動的に呼び出されます。

フォーム要素で (値の代わりに) ng-model を使用する場合、成功のコールバックで model/$scope プロパティを変更でき、フォームは自動的に更新されます (ng-model による双方向データバインディングのため)。ただし、フォームを送信しようとする代わりに、コントローラー内で $http または $resource サービスを使用して Web サービスを呼び出してみませんか? (そのため、ユーザーが私のコメントに関与する必要があるかどうかを尋ねました。)

于 2013-01-21T22:58:37.410 に答える
0

$http のようなものを使用していると仮定すると、すでに angular スコープ内にあり、手動で $scope.apply(); を呼び出す必要はありません。あなたはすでに角度のある実行の中にいるので。

$scope.apply() を捨てて、単に

.success(function(data) {
     paymentModel.urlFromTheResponse = data.url;
     paymentModel.accessCode = data.accessCode;
 $http.post("/finalstep",paymentModel).success(function(data)
{
// other stuff
});
}
于 2013-01-22T13:04:40.157 に答える