537

$watchAngularJS は、イベントのように、モデルの状態を常にチェックするなど、いくつかのコードを 2 回、時にはそれ以上実行することを理解しています。

ただし、私のコード:

function MyController($scope, User, local) {

var $scope.User = local.get(); // Get locally save user data

User.get({ id: $scope.User._id.$oid }, function(user) {
  $scope.User = new User(user);
  local.save($scope.User);
});

//...

私のDBに2つのレコードを挿入して、2回実行されます。私は何年にもわたってこれに頭をぶつけてきたので、明らかにまだ学んでいます!

4

24 に答える 24

1054

アプリルーターはナビゲーションをMyController次のように指定しました:

$routeProvider.when('/',
                   { templateUrl: 'pages/home.html',
                     controller: MyController });

しかし、私はこれも持っていましたhome.html:

<div data-ng-controller="MyController">

これにより、コントローラーが 2 回消化されました。data-ng-controllerHTML から属性を削除すると、問題が解決しました。または、controller:プロパティがルーティング ディレクティブから削除されている可能性があります。

この問題は、タブ ナビゲーションを使用している場合にも発生します。たとえば、次のものapp.jsが含まれる場合があります。

  .state('tab.reports', {
    url: '/reports',
    views: {
      'tab-reports': {
        templateUrl: 'templates/tab-reports.html',
        controller: 'ReportsCtrl'
      }
    }
  })

対応するレポート タブの HTML は次のようになります。

<ion-view view-title="Reports">
  <ion-content ng-controller="ReportsCtrl">

これにより、コントローラーが 2 回実行されることにもなります。

于 2013-03-20T22:08:26.263 に答える
129

AngularJS docs - ngController
$route サービスを介してルート定義で宣言することにより、コントローラーを DOM にアタッチすることもできることに注意してください。よくある間違いは、テンプレート自体で ng-controller を使用してコントローラーを再度宣言することです。これにより、コントローラーがアタッチされ、2 回実行されます。

ディレクティブでngRoute を使用するとng-view、コントローラーはデフォルトでその dom 要素 (または ui-router を使用する場合は ui-view) にアタッチされます。したがって、テンプレートに再度添付する必要はありません。

于 2014-10-02T08:46:50.630 に答える
70

これを実行しましたが、問題は受け入れられた回答とは異なりました。将来の自分のために、これを修正するために行った手順を含めるために、ここに残しておきます。

  1. 冗長なコントローラー宣言を削除する
  2. ルートの末尾のスラッシュを確認する
  3. チェックng-ifs
  4. 不要なラッピングng-view呼び出しがないか確認してください (ng-view実際の をラップしていた を誤って残してしまいましたng-view。これにより、コントローラーが 3 回呼び出されました。)
  5. Rails を使用している場合はturbolinks、ファイルから gemを削除する必要がありapplication.jsます。私はそれを発見するために一日を無駄にしました。ここで答えが見つかりました。
  6. ng-app と bootstrap を使用してアプリを 2 回初期化します。コントローラーを実行するAngularJSと2回戦う
  7. 独自のコントローラーも定義されており、ng-click などを介してテンプレートでこのコントローラーのコールバックを使用するディレクティブの 'link'-function の要素全体で $compile を使用する場合。ここで回答が見つかりました。
于 2015-03-24T18:52:00.243 に答える
14

コントローラーが2回初期化できる場合をもう1つ追加したいだけです(これはangular.js 1.3.1の実際です):

<div ng-if="loading">Loading...</div>
<div ng-if="!loading">
    <div ng-view></div>
</div>

この場合、 $route.current は ng-view が初期化されるときにすでに設定されています。これにより、二重の初期化が発生します。

それを修正するには、ng-if を ng-show/ng-hide に変更するだけで、すべてうまくいきます。

于 2014-11-17T11:08:58.260 に答える
7

参考のために追加したい:

コントローラー コードの二重実行は、ページでも実行されるディレクティブでコントローラーを参照することによっても発生する可能性があります。

例えば

return {

            restrict: 'A',
            controller: 'myController',
            link: function ($scope) { ....

HTML に ng-controller="myController" もある場合

于 2014-10-28T18:19:21.337 に答える
6

この問題について、アプリとそのすべての依存関係を少しずつ引き裂きました (詳細はこちら: AngularJS app initiating 2 回 (通常のソリューションを試しました..) )

結局、それはすべて Batarang Chrome プラグインのせいでした。

この回答の解決策:

コードを変更する前に、投稿ごとにそれを無効にすることを、誰のリストでも最初にすることを強くお勧めします。

于 2015-05-07T08:56:34.137 に答える
5

単純なアプリ (ルーティングと単純な ng-controller 参照なし) で同じ問題が発生し、コントローラーのコンストラクターが 2 回実行されました。最後に、Razor ビューで AngularJS アプリケーションを自動ブートストラップする次の宣言が問題であることがわかりました。

<html ng-app="mTest1">

angular.bootstrap ieを使用して手動でブートストラップしました

angular.bootstrap(document, [this.app.name]);

それらの1つを削除すると、うまくいきました。

于 2015-01-27T14:33:07.383 に答える
5

コントローラーが意図せずに複数回実行されていることがわかっている場合は、問題のあるコントローラーの名前をファイルで検索してみてください。例: search: MyController through all files. おそらく他のhtml/jsファイルにコピーアンドペーストされ、それらのパーシャル/コントローラーを開発または使用するときに変更するのを忘れました. 出典:こんなミスをした

于 2014-08-01T22:49:28.147 に答える
2

AngularJS 1.4 rc ビルドでこの問題に頭を悩ませていたところ、この記事の執筆時点でAngular 1.4 および Angular 2 の新しいルーター ライブラリから作成されたため、上記の回答はどれも当てはまらないことに気付きました。したがって、新しい Angular ルート ライブラリを使用している可能性がある人のために、ここにメモを残します。

基本的に、html ページにng-viewportアプリの一部をロードするためのディレクティブが含まれている場合、 with で指定されたハイパーリンクをクリックするng-linkと、関連付けられたコンポーネントのターゲット コントローラーが 2 回ロードされます。微妙な違いは、ブラウザーが既にターゲット コントローラーを読み込んでいる場合、同じハイパーリンクを再度クリックしても、コントローラーは 1 回しか呼び出されないことです。

実行可能な回避策はまだ見つかっていませんが、この動作はshaunxuによって提起された観察と一致していると思います。うまくいけば、この問題は新しいルート ライブラリの将来のビルドと AngularJS 1.4 リリースで解決されるでしょう。

于 2015-05-22T22:49:11.627 に答える
2

私が遭遇している問題は接線かもしれませんが、グーグルでこの質問にたどり着いたので、これは適切かもしれません. この問題は、UI Router を使用しているときに頭を悩ませますが、それはブラウザの更新ボタンでページを更新しようとしたときだけです。このアプリは、親の抽象状態で UI Router を使用し、次に子の状態を親から切り離します。アプリrun()機能には、$state.go('...child-state...')コマンドがあります。親状態は を使用してresolveおり、最初はおそらく子コントローラーが 2 回実行されているのではないかと思いました。

URL にハッシュが追加される前は、すべて問題ありません。
www.someoldwebaddress.org

その後、URL が UI Router によって変更されると、
www.someoldwebaddress.org#/childstate

...そして、ブラウザの更新ボタンでページを更新すると、$stateChangeStartが 2 回起動し、そのたびにchildstate.

親状態のresolveは、2 回発火しているものです。

おそらくこれはクラッジです。$stateProviderが最初に呼び出されるコードの領域で、最初にwindow.location.hashが空の文字列かどうかを確認します。もしそうなら、すべてが良いです。そうでない場合は、window.location.hashを空の文字列に設定します。それから、$stateどこかに行こうとするのは 2 回ではなく 1 回だけのようです。

runまた、アプリの既定値とに依存したくない場合はstate.go(...)、ハッシュ値をキャプチャし、そのハッシュ値を使用して、ページを更新する直前にあった子状態を特定し、その領域に条件を追加することができます。を設定するコードstate.go(...)

于 2015-09-09T04:44:10.050 に答える
2

私の場合、同じコントローラーを使用する 2 つのビューを見つけました。

$stateProvider.state('app', {
  url: '',
  views: {
    "viewOne@app": {
      controller: 'CtrlOne as CtrlOne',
      templateUrl: 'main/one.tpl.html'
    },
    "viewTwo@app": {
      controller: 'CtrlOne as CtrlOne',
      templateUrl: 'main/two.tpl.html'
    }
  }
});
于 2015-08-12T01:36:58.583 に答える
1

私の問題は、検索パラメータを次のように更新していました$location.search('param', key);

あなたはそれについてもっと読むことができます ここ

URLにパラメーターを追加するため、コントローラーが2回呼び出される

于 2016-09-22T12:41:25.947 に答える
1

私の場合、コントローラーの名前を別の名前に変更すると問題が解決しました。

angular-ui-tree 」モジュールとコントローラー名の競合がありました。コントローラーの名前を「 CatalogerTreeController 」から「TreeController 」に変更すると、このコントローラーは「 ui-tree」ディレクティブが使用されているページで2回開始されます。このディレクティブは、「TreeController」という名前のコントローラーを使用します。

于 2017-11-20T15:16:50.840 に答える
0

私は同じ問題を抱えていましたが、すべての答えを試した後、同じコントローラーにバインドされたディレクティブがビューにあることが最終的にわかりました。

APP.directive('MyDirective', function() {
  return {
    restrict: 'AE',
    scope: {},
    templateUrl: '../views/quiz.html',
    controller: 'ShowClassController'
}
});

ディレクティブを削除した後、コントローラーは 2 回呼び出されなくなりました。今私の質問は、この問題なしでコントローラースコープにバインドされたこのディレクティブをどのように使用できるかということです。

于 2016-06-28T12:01:35.213 に答える
0

正規表現ルートの最後に余分なスラッシュangular-route@1.6.7があるため、同じ問題があります。

.when('/goods/publish/:classId/', option)

.when('/goods/publish/:classId', option)

そしてそれは正しく動作します。

于 2018-03-28T09:03:39.760 に答える
0

ここにも私のケースを追加するだけです:

angular-ui-routerを使用していました$state.go('new_state', {foo: "foo@bar"})

パラメーターにencodeURIComponentを追加すると、問題はなくなりました: $state.go('new_state', {foo: encodeURIComponent("foo@bar")}).

どうしたの?パラメータ値の文字「@」は、URL では使用できません。その結果、angular-ui-router はコントローラーを 2 回作成しました。最初の作成では元の「foo@bar」を渡し、2 回目の作成ではエンコードされたバージョンの「foo%40bar」を渡しました。上記のようにパラメーターを明示的にエンコードすると、問題はなくなりました。

于 2020-05-17T12:52:15.813 に答える