0

controller as構文に関しては、これまで一度も使用したことがないため、少し混乱しています。これを修正する正しい方法を知りたいです。検索しても同様の問題は見つかりませんでした。

メニューとメニューを切り替えるボタンがあります。メニューには独自のスコープがあり、ボタンには別のスコープがあります。これらは 2 つの別個のファイルとコンテナーに存在するからです。

nav.isActiveボタンをクリックすると、ボタンの範囲内でのみ更新されます。状態を保存するためのサービスを作成しましたが、これは考えたときに行う必要はありません..すべきでしょうか? その値が変化したかどうかを監視する唯一の方法はウォッチャーを使用することであり、機能がない$scopeため使用する必要がありますが、パフォーマンスに影響を与えるため、これをできる限り避けたいと考えています。このプロジェクトでは重要です。this$watch

controller as構文を使用するときに、別の「スコープ」から「スコープ」変数を更新する正しい方法は何ですか?

コントローラ:

nav.controller('NavCtrl', ['navState', function(navState) {

  var nav = this;

  nav.menu = [
    {icon: 'color_lens', href: ''},
    {icon: 'color_lens', href: 'about'},
    {icon: 'color_lens', href: 'contact'},
    {icon: 'color_lens', href: 'logout'},
    {icon: 'color_lens', href: 'faq'}
  ];

  nav.toggleMenu = function() {
    nav.isActive = navState.checkState();
  }

}]);

あるスコープから別のスコープに値を渡すためのサービス:

nav.service('navState', [function() {

  var isActive = false;

  this.checkState = function() {

    isActive = !isActive;

    return !isActive;
  }
}]);

メニュー マークアップ (menu.html):

<nav class="si-wrapper si-dark" ng-controller="NavCtrl as nav" ng-class="{active: nav.isActive}">
  <ul class="si-list">
    <li class="si-item" ng-repeat="item in nav.menu">
      <a href="#/{{item.href}}">
        <div class="si-inner-item">
          <i class="material-icons md-36" ng-bind="item.icon"></i>
        </div>
      </a>
    </li>
  </ul>
  <h1>{{nav.isActive}}</h1> <!-- This doesn't change -->
</nav>

メニューを切り替えるボタン (header.html):

<div ng-controller="NavCtrl as nav">
  <button ng-click="nav.toggleMenu()">Toggle</button>
  <span>{{nav.isActive}}</span> <!-- This updates however -->
</div>
4

2 に答える 2

2

あなたの問題はnav.isActive、コントローラーの1つに設定されていないことです。ng-controller基本的に、新しいコントローラー (および)を使用するたびに$scope作成されます。したがって、コントローラーごとに$scope.isActive、関連するビューがそれを参照するように設定する必要があります。

投稿されたコードでisActiveは、実行時にのみ設定されますtoggleMenu()。これは、header.html でのみ発生します。

コードを機能させるにはisActive、コントローラーの負荷を設定するだけです。例えば:

nav.controller('NavCtrl', ['navState', function(navState) {
    // put isActive on the scope on controller load
    this.activeState = navState.getState();

    nav.toggleMenu = function() {
        navState.toggleState();
    };
}]);

状態アクセスと状態操作を分離して、サービスを改善する必要があります。また、コンテナ オブジェクトにラップすると、スコープ階層の問題が発生しなくなります。

nav.service('navState', [function() {

    var state = {
        isActive: false
    };

    this.toggleState = function() {
        state.isActive = !state.isActive;
    };

    this.getState = function(){
        return state;
    };
}]);

次に、ビュー内で「activeState.isActive」を使用する必要があります。

これで、共有可能な状態のサービスと、ロード時に両方が同じサービスを参照する 2 つのコントローラーができました。次に、メニュー ビュー内で状態を切り替えると、両方のコントローラー スコープが更新されます。

于 2015-11-14T22:20:30.540 に答える
0

angularjs ドキュメントから:

Controller が ng-controller ディレクティブを介して DOM にアタッチされると、Angular は、指定された Controller のコンストラクター関数を使用して、新しい Controller オブジェクトをインスタンス化します。新しい子スコープが作成され、コントローラーのコンストラクター関数に $scope として注入可能なパラメーターとして使用できるようになります。

さらに、ng-controller ディレクティブには、親スコープから継承するスコープがあります。したがって、親で共有データを定義することもできます。「NavCtrl」スコープでアクセスできます。しかし、コントローラを synax として使用したいので、サービスの助けを借りてデータを共有するのが 1 つの方法です。

ただし、「ng-controller」ディレクティブを使用したアプローチは好きではありません。もう 1 つの解決策は、子ディレクティブが親ディレクティブを必要とするディレクティブの階層に置き換えることです。そこで「controllerAs」プロパティも使用します。

于 2015-11-14T23:01:36.083 に答える