4

私は AngularJS を使用しており、独自のコントローラーを持つディレクティブがあります。親コントローラーのスコープを継承します。

例として、次のことを考慮してください。

function ParentCtrl() {
    $scope.aMethod = function() {
        // DO SOMETHING
    };
}

function ChildCtrl() {
    $scope.bMethod = function() {
        // DO SOMETHING ELSE
    }
}  

現在、$scope.aMethodParentCtrl() は ng-click ディレクティブによってトリガーされます。私がやりたいのは$scope.bMethod、ChildCtrl() の呼び出しです。どうすればいいですか?

編集: いくつかの詳細情報。ParentCtrl に関連付けられたテンプレートには、ボタンと複数のディレクティブがあります。各ディレクティブは、異なる入力セットを持つフォームをロードします。ng-switch onParentCtrl テンプレートのボタンをクリックすると、とによってディレクティブが次々と読み込まれng-switch-whenます。
ユーザーがボタンをクリックすると、ディレクティブに属する ChildCtrl は、データをそれぞれのフォームに保存することを意図しています。
したがって、ボタンがクリックされると、次のようになります。
1. ChildCtrl は、ロードされた現在のディレクティブに関連付けられたモデルを保存します。
2. ParentCtrl は、シリーズの次のディレクティブをロードします。
ng-clickParentCtrl に関連付けられたボタンにバインドされます。ただし、そのボタンがクリックされたときに、ChildCtrl も何らかのアクション (フォーム データを保存する) を実行する必要があります。どうやってそれを達成するのですか?

4

2 に答える 2

9

以下をご覧ください。

の概念を使用してい$broadcastます。親コントローラー、独自のコントローラーを持つ子ディレクティブなど、あなたが与えたシナリオを複製するのにうんざりしています。

var animateAppModule = angular.module('animateApp', [])
animateAppModule.controller('tst', function($scope) {
  $scope.test = function() {
    $scope.$broadcast('clickMessageFromParent', {
      data: "SOME msg to the child"
    })
  }
}).directive('myDirective', function() {
  return {
    controller: function($scope) {

    },
    link: function($scope, element) {
      $scope.$on('clickMessageFromParent', function(scopeDetails, msgFromParent) {
        //console.log(msgFromParent)
        element[0].innerHTML = msgFromParent.data;
      })
    }
  }
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-controller="tst">
  <input type="button" ng-click="test()" value="click" />
  <div my-directive="somvalue"></div>
</div>

JSFiddle

于 2013-03-01T19:42:38.997 に答える
4

これは、ブロードキャストを使用する必要があるという点で、rajkamal が言っていることに似ていますが、ブロードキャストを動的に変更して、必要な子をターゲットにする必要があります。

ここに例を示すプランカーがあります

コードは次のとおりです。

app.controller('MainCtrl', function($scope) {

  // a method that broadcasts to a selected child.
  $scope.broadcastToSelectedChild = function (){
    $scope.$broadcast('call-' + $scope.broadcastTo);
  };
});

app.directive('testDir', function (){
  return {
    restrict: 'E',
    scope: {
      'name': '@'
    },
    template: '<div>{{name}} called: {{called}}</div>',
    link: function(scope, elem, attr) {

      scope.called = false;

      //a child function to call.
      scope.childFunction = function (){
        scope.called = true;
      };

      //set up the name to be used as the listened to event.
      var removeOn;
      scope.$watch('name', function(v) {
        if(removeOn) removeOn();
        removeOn = scope.$on('call-' + scope.name, function (){
            scope.childFunction();
          });
      });
    }
  };
});

ここにHTMLがあります:

  <div ng-controller="MainCtrl">
    <test-dir name="test1"></test-dir>
    <test-dir name="test2"></test-dir>
    <test-dir name="test3"></test-dir>
    <select ng-model="broadcastTo" ng-options="x as x for x in ['test1', 'test2', 'test3']"></select>
    <button ng-click="broadcastToSelectedChild()">test</button>
  </div>

ここで行ったことは、ディレクティブに名前を付けて、名前でブロードキャストできるメカニズムを作成することです。コードが自明でない場合は、お知らせください。これが役立つことを願っています。

于 2013-03-01T20:43:41.340 に答える