web-dev-qa-db-ja.com

Angularjs:親ディレクティブのスコープ値を子ディレクティブで設定します

これがこれを行う方法かどうかはわかりませんが、私の目標は次のとおりです。

  • 親ディレクティブがあります
  • 親ディレクティブのブロック内に、ユーザーから入力を取得する子ディレクティブがあります
  • 子ディレクティブは、親ディレクティブのスコープに値を設定します
  • 私はそこからそれを取ることができます

もちろん問題は、親と子のディレクティブが兄弟であるということです。だから私はこれを行う方法がわかりません。注-データを設定したくない

フィドル: http://jsfiddle.net/rrosen326/CZWS4/

html:

<div ng-controller="parentController">
    <parent-dir dir-data="display this data">
        <child-dir></child-dir>
    </parent-dir>
</div>

Javascript

var testapp = angular.module('testapp', []);

testapp.controller('parentController', ['$scope', '$window', function ($scope, $window) {
    console.log('parentController scope id = ', $scope.$id);
    $scope.ctrl_data = "irrelevant ctrl data";
}]);

testapp.directive('parentDir', function factory() {
    return {
        restrict: 'ECA',
        scope: {
            ctrl_data: '@'
        },
        template: '<div><b>parentDir scope.dirData:</b> {{dirData}} <div class="offset1" ng-transclude></div> </div>',
        replace: false,
        transclude: true,
        link: function (scope, element, attrs) {
            scope.dirData = attrs.dirData;
            console.log("parent_dir scope: ", scope.$id);
        }
    };
});

testapp.directive('childDir', function factory() {
    return {
        restrict: 'ECA',
        template: '<h4>Begin child directive</h4><input type="text"  ng-model="dirData" /></br><div><b>childDir scope.dirData:</b> {{dirData}}</div>',
        replace: false,
        transclude: false,
        link: function (scope, element, attrs) {
            console.log("child_dir scope: ", scope.$id);
            scope.dirData = "No, THIS data!"; // default text
        }
    };
});
12
Ross R

この種の通信が必要な場合は、子ディレクティブでrequireを使用する必要があります。これには親controllerが必要になるため、子ディレクティブで使用する機能を備えたcontrollerが必要です。

例えば:

app.directive('parent', function() {
  return {
    restrict: 'E',
    transclude: true,
    template: '<div>{{message}}<span ng-transclude></span></div>',
    controller: function($scope) {
      $scope.message = "Original parent message"

      this.setMessage = function(message) {
        $scope.message = message;
      }
    }
  }
});

コントローラの$scopeにメッセージがあり、それを変更する方法があります。

なぜ1つは$scopeにあり、もう1つはthisを使用しているのですか?子ディレクティブの$scopeにアクセスできないため、子ディレクティブが呼び出すことができるように、関数でthisを使用する必要があります。

app.directive('child', function($timeout) {
  return {
    restrict: 'E',
    require: '^parent',
    link: function(scope, elem, attrs, parentCtrl) {
      $timeout(function() {
        parentCtrl.setMessage('I am the child!')
      }, 3000)
    }
  }
})

ご覧のとおり、リンクは、parentCtrl(または複数ある場合は配列)を使用して4番目のパラメーターを受け取ります。ここでは、親コントローラーで定義したメソッドを呼び出してメッセージを変更するまで3秒待ちます。

ここでライブをご覧ください: http://plnkr.co/edit/72PjQSOlckGyUQnH7zOA?p=preview

27
Jesus Rodriguez

まず、 このビデオ を見てください。それはそれをすべて説明します。

基本的に、require: '^parentDir'する必要があります。そうすると、リンク関数に渡されます。

link: function (scope, element, attrs, ParentCtrl) {
    ParentCtrl.$scope.something = '';
}
6
Brian Genisio