Wie kann ich aus einer benutzerdefinierten Direktive * mit eigenem Gültigkeitsbereich * in AngularJS auf den übergeordneten Bereich zugreifen?

327

Ich suche nach einer Möglichkeit, innerhalb einer Direktive auf den "übergeordneten" Bereich zuzugreifen. Jede Kombination von Gültigkeitsbereich, Transklusion, Anforderung, Übergabe von Variablen (oder des Gültigkeitsbereichs selbst) von oben usw. Ich bin absolut bereit, mich nach hinten zu beugen, aber ich möchte etwas vermeiden, das völlig hackig oder nicht wartbar ist. Ich weiß zum Beispiel, dass ich es jetzt tun kann, indem ich die $scopepreLink-Parameter nehme und über die $siblingBereiche iteriere , um das konzeptionelle "übergeordnete Element " zu finden.

Was ich wirklich möchte, ist, $watcheinen Ausdruck im übergeordneten Bereich zu können. Wenn ich das kann, kann ich das erreichen, was ich hier versuche: AngularJS - Wie rendere ich einen Teil mit Variablen?

Ein wichtiger Hinweis ist, dass die Richtlinie im selben übergeordneten Bereich wiederverwendbar sein muss. Daher funktioniert das Standardverhalten (Gültigkeitsbereich: false) bei mir nicht. Ich benötige einen individuellen Bereich pro Instanz der Direktive und dann $watcheine Variable, die im übergeordneten Bereich lebt.

Ein Codebeispiel sagt mehr als 1000 Wörter.

app.directive('watchingMyParentScope', function() {
    return {
        require: /* ? */,
        scope: /* ? */,
        transclude: /* ? */,
        controller: /* ? */,
        compile: function(el,attr,trans) {
            // Can I get the $parent from the transclusion function somehow?
            return {
                pre: function($s, $e, $a, parentControl) {
                    // Can I get the $parent from the parent controller?
                    // By setting this.$scope = $scope from within that controller?

                    // Can I get the $parent from the current $scope?

                    // Can I pass the $parent scope in as an attribute and define
                    // it as part of this directive's scope definition?

                    // What don't I understand about how directives work and
                    // how their scope is related to their parent?
                },
                post: function($s, $e, $a, parentControl) {
                    // Has my situation improved by the time the postLink is called?
                }
            }
        }
    };
});
Colllin
quelle

Antworten:

644

Siehe Was sind die Nuancen der prototypischen / prototypischen Vererbung von Scope in AngularJS?

Zusammenfassend lässt sich sagen, wie eine Direktive auf ihren übergeordneten Bereich ( $parent) zugreift, hängt von der Art des Bereichs ab, den die Direktive erstellt:

  1. default ( scope: false) - Die Direktive erstellt keinen neuen Bereich, daher gibt es hier keine Vererbung. Der Geltungsbereich der Direktive entspricht dem Geltungsbereich des übergeordneten / Containers. Verwenden Sie in der Verknüpfungsfunktion den ersten Parameter (normalerweise scope).

  2. scope: true- Die Direktive erstellt einen neuen untergeordneten Bereich, der prototypisch vom übergeordneten Bereich erbt. Eigenschaften, die im übergeordneten Bereich definiert sind, stehen der Direktive zur Verfügung scope(aufgrund der prototypischen Vererbung). Achten Sie nur darauf, dass Sie nicht in eine primitive Bereichseigenschaft schreiben. Dadurch wird eine neue Eigenschaft für den Direktivenbereich erstellt (die die gleichnamige übergeordnete Bereichseigenschaft verbirgt / schattiert).

  3. scope: { ... }- Die Richtlinie schafft einen neuen isolierten / isolierten Bereich. Der übergeordnete Bereich wird nicht prototypisch geerbt. Sie können weiterhin mit auf den übergeordneten Bereich zugreifen $parent, dies wird jedoch normalerweise nicht empfohlen. Stattdessen sollten Sie die übergeordneten Bereich Eigenschaften (und / oder Funktion) die Richtlinie Bedarf über zusätzliche Attribute auf demselben Elemente angeben , in dem die Richtlinie verwendet wird, mit der =, @und &Notation.

  4. transclude: true- Die Richtlinie erstellt einen neuen "transkludierten" untergeordneten Bereich, der prototypisch vom übergeordneten Bereich erbt. Wenn die Direktive auch einen isolierten Bereich erstellt, sind der transkludierte und der isolierte Bereich Geschwister. Die $parentEigenschaft jedes Bereichs verweist auf denselben übergeordneten Bereich.
    Angular v1.3-Update : Wenn die Direktive auch einen isolierten Bereich erstellt, ist der transkludierte Bereich jetzt ein untergeordnetes Element des isolierten Bereichs. Die transkludierten und isolierten Bereiche sind keine Geschwister mehr. Die $parentEigenschaft des transkludierten Bereichs verweist jetzt auf den isolierten Bereich.

Der obige Link enthält Beispiele und Bilder aller 4 Typen.

Sie können in der Kompilierungsfunktion der Direktive nicht auf den Bereich zugreifen (wie hier erwähnt: https://github.com/angular/angular.js/wiki/Understanding-Directives ). Sie können auf den Geltungsbereich der Direktive in der Link-Funktion zugreifen.

Aufpassen:

Für 1. und 2. oben: Normalerweise geben Sie über ein Attribut an, welche übergeordnete Eigenschaft die Direktive benötigt, und dann $ watch it:

<div my-dir attr1="prop1"></div>

scope.$watch(attrs.attr1, function() { ... });

Wenn Sie eine Objekteigenschaft beobachten, müssen Sie $ parse verwenden:

<div my-dir attr2="obj.prop2"></div>

var model = $parse(attrs.attr2);
scope.$watch(model, function() { ... });

Beobachten Sie für 3. oben (Bereich isolieren) den Namen, den Sie der Direktiveigenschaft mit der Notation @oder geben =:

<div my-dir attr3="{{prop3}}" attr4="obj.prop4"></div>

scope: {
  localName3: '@attr3',
  attr4:      '='  // here, using the same name as the attribute
},
link: function(scope, element, attrs) {
   scope.$watch('localName3', function() { ... });
   scope.$watch('attr4',      function() { ... });
Mark Rajcok
quelle
1
DANKE, Mark. Es stellt sich heraus, dass die Lösung, die ich unter Wie man einen Teil mit Variablen rendert , wirklich sehr gut funktioniert. Was Sie wirklich brauchten, um mich zu verlinken, war etwas mit dem Titel "Die Nuancen des Schreibens von HTML und des Erkennens, dass Ihr Element nicht in dem ng-Controller verschachtelt ist, von dem Sie glauben, dass es es ist." Wow ... Anfängerfehler. Dies ist jedoch eine nützliche Ergänzung zu Ihrer anderen (viel längeren) Antwort, in der Bereiche erläutert werden.
Colllin
@collin, großartig, ich bin froh, dass du dein Problem gelöst hast, da ich nicht ganz sicher war, wie ich auf deinen anderen (jetzt gelöschten) Kommentar reagieren soll.
Mark Rajcok
Was kann / soll ich tunscope.$watch('localName3', function() { ...[?? WHAT TO DO HERE for example?] });
Junaid Qadir
1
@Andy, nein nicht verwenden $parsemit =: Geige . $parsewird nur bei nicht isolierten Bereichen benötigt.
Mark Rajcok
1
Dies ist eine großartige Antwort, sehr gründlich. Es zeigt auch, warum ich es einfach hasse, mit AngularJS zu arbeiten.
John Trichereau
51

Der Zugriff auf die Controller-Methode bedeutet den Zugriff auf eine Methode im übergeordneten Bereich über die Direktive controller / link / scope.

Wenn die Direktive den übergeordneten Bereich gemeinsam nutzt / erbt, ist es ganz einfach, nur eine übergeordnete Bereichsmethode aufzurufen.

Es ist wenig mehr Arbeit erforderlich, wenn Sie über den Bereich der isolierten Direktive auf die übergeordnete Bereichsmethode zugreifen möchten.

Es gibt nur wenige Optionen (möglicherweise mehr als unten aufgeführt), um eine übergeordnete Bereichsmethode aus dem Bereich isolierter Direktiven aufzurufen oder übergeordnete Bereichsvariablen zu überwachen ( Option 6 speziell).

Beachten Sie, dass ich link functionin diesen Beispielen verwendet habe, aber Sie können je directive controllernach Anforderung auch ein verwenden.

Option 1. Durch Objektliteral und aus Direktive HTML-Vorlage

index.html

<!DOCTYPE html>
<html ng-app="plunker">

  <head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>
    <script>document.write('<base href="' + document.location + '" />');</script>
    <link rel="stylesheet" href="style.css" />
    <script data-require="[email protected]" src="https://code.angularjs.org/1.3.9/angular.js" data-semver="1.3.9"></script>
    <script src="app.js"></script>
  </head>

  <body ng-controller="MainCtrl">
    <p>Hello {{name}}!</p>

    <p> Directive Content</p>
    <sd-items-filter selected-items="selectedItems" selected-items-changed="selectedItemsChanged(selectedItems)" items="items"> </sd-items-filter>


    <P style="color:red">Selected Items (in parent controller) set to: {{selectedItemsReturnedFromDirective}} </p>

  </body>

</html>

itemfilterTemplate.html

<select ng-model="selectedItems" multiple="multiple" style="height: 200px; width: 250px;" ng-change="selectedItemsChanged({selectedItems:selectedItems})" ng-options="item.id as item.name group by item.model for item in items | orderBy:'name'">
  <option>--</option>
</select>

app.js

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

app.directive('sdItemsFilter', function() {
  return {
    restrict: 'E',
    scope: {
      items: '=',
      selectedItems: '=',
      selectedItemsChanged: '&'
    },
    templateUrl: "itemfilterTemplate.html"
  }
})

app.controller('MainCtrl', function($scope) {
  $scope.name = 'TARS';

  $scope.selectedItems = ["allItems"];

  $scope.selectedItemsChanged = function(selectedItems1) {
    $scope.selectedItemsReturnedFromDirective = selectedItems1;
  }

  $scope.items = [{
    "id": "allItems",
    "name": "All Items",
    "order": 0
  }, {
    "id": "CaseItem",
    "name": "Case Item",
    "model": "PredefinedModel"
  }, {
    "id": "Application",
    "name": "Application",
    "model": "Bank"
    }]

});

Arbeitsplnkr: http://plnkr.co/edit/rgKUsYGDo9O3tewL6xgr?p=preview

Option 2. Durch Object Literal und von Direktive Link / Scope

index.html

<!DOCTYPE html>
<html ng-app="plunker">

  <head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>
    <script>document.write('<base href="' + document.location + '" />');</script>
    <link rel="stylesheet" href="style.css" />
    <script data-require="[email protected]" src="https://code.angularjs.org/1.3.9/angular.js" data-semver="1.3.9"></script>
    <script src="app.js"></script>
  </head>

  <body ng-controller="MainCtrl">
    <p>Hello {{name}}!</p>

    <p> Directive Content</p>
    <sd-items-filter selected-items="selectedItems" selected-items-changed="selectedItemsChanged(selectedItems)" items="items"> </sd-items-filter>


    <P style="color:red">Selected Items (in parent controller) set to: {{selectedItemsReturnedFromDirective}} </p>

  </body>

</html>

itemfilterTemplate.html

<select ng-model="selectedItems" multiple="multiple" style="height: 200px; width: 250px;" 
 ng-change="selectedItemsChangedDir()" ng-options="item.id as item.name group by item.model for item in items | orderBy:'name'">
  <option>--</option>
</select>

app.js

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

app.directive('sdItemsFilter', function() {
  return {
    restrict: 'E',
    scope: {
      items: '=',
      selectedItems: '=',
      selectedItemsChanged: '&'
    },
    templateUrl: "itemfilterTemplate.html",
    link: function (scope, element, attrs){
      scope.selectedItemsChangedDir = function(){
        scope.selectedItemsChanged({selectedItems:scope.selectedItems});  
      }
    }
  }
})

app.controller('MainCtrl', function($scope) {
  $scope.name = 'TARS';

  $scope.selectedItems = ["allItems"];

  $scope.selectedItemsChanged = function(selectedItems1) {
    $scope.selectedItemsReturnedFromDirective = selectedItems1;
  }

  $scope.items = [{
    "id": "allItems",
    "name": "All Items",
    "order": 0
  }, {
    "id": "CaseItem",
    "name": "Case Item",
    "model": "PredefinedModel"
  }, {
    "id": "Application",
    "name": "Application",
    "model": "Bank"
    }]
});

Arbeitsplnkr: http://plnkr.co/edit/BRvYm2SpSpBK9uxNIcTa?p=preview

Option 3. Durch Funktionsreferenz und aus Direktive HTML-Vorlage

index.html

<!DOCTYPE html>
<html ng-app="plunker">

  <head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>
    <script>document.write('<base href="' + document.location + '" />');</script>
    <link rel="stylesheet" href="style.css" />
    <script data-require="[email protected]" src="https://code.angularjs.org/1.3.9/angular.js" data-semver="1.3.9"></script>
    <script src="app.js"></script>
  </head>

  <body ng-controller="MainCtrl">
    <p>Hello {{name}}!</p>

    <p> Directive Content</p>
    <sd-items-filter selected-items="selectedItems" selected-items-changed="selectedItemsChanged" items="items"> </sd-items-filter>


    <P style="color:red">Selected Items (in parent controller) set to: {{selectedItemsReturnFromDirective}} </p>

  </body>

</html>

itemfilterTemplate.html

<select ng-model="selectedItems" multiple="multiple" style="height: 200px; width: 250px;" 
 ng-change="selectedItemsChanged()(selectedItems)" ng-options="item.id as item.name group by item.model for item in items | orderBy:'name'">
  <option>--</option>
</select>

app.js

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

app.directive('sdItemsFilter', function() {
  return {
    restrict: 'E',
    scope: {
      items: '=',
      selectedItems:'=',
      selectedItemsChanged: '&'
    },
    templateUrl: "itemfilterTemplate.html"
  }
})

app.controller('MainCtrl', function($scope) {
  $scope.name = 'TARS';

  $scope.selectedItems = ["allItems"];

  $scope.selectedItemsChanged = function(selectedItems1) {
    $scope.selectedItemsReturnFromDirective = selectedItems1;
  }

  $scope.items = [{
    "id": "allItems",
    "name": "All Items",
    "order": 0
  }, {
    "id": "CaseItem",
    "name": "Case Item",
    "model": "PredefinedModel"
  }, {
    "id": "Application",
    "name": "Application",
    "model": "Bank"
    }]
});

Arbeitsplnkr: http://plnkr.co/edit/Jo6FcYfVXCCg3vH42BIz?p=preview

Option 4. Durch Funktionsreferenz und aus Direktivenlink / Geltungsbereich

index.html

<!DOCTYPE html>
<html ng-app="plunker">

  <head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>
    <script>document.write('<base href="' + document.location + '" />');</script>
    <link rel="stylesheet" href="style.css" />
    <script data-require="[email protected]" src="https://code.angularjs.org/1.3.9/angular.js" data-semver="1.3.9"></script>
    <script src="app.js"></script>
  </head>

  <body ng-controller="MainCtrl">
    <p>Hello {{name}}!</p>

    <p> Directive Content</p>
    <sd-items-filter selected-items="selectedItems" selected-items-changed="selectedItemsChanged" items="items"> </sd-items-filter>


    <P style="color:red">Selected Items (in parent controller) set to: {{selectedItemsReturnedFromDirective}} </p>

  </body>

</html>

itemfilterTemplate.html

<select ng-model="selectedItems" multiple="multiple" style="height: 200px; width: 250px;" ng-change="selectedItemsChangedDir()" ng-options="item.id as item.name group by item.model for item in items | orderBy:'name'">
  <option>--</option>
</select>

app.js

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

app.directive('sdItemsFilter', function() {
  return {
    restrict: 'E',
    scope: {
      items: '=',
      selectedItems: '=',
      selectedItemsChanged: '&'
    },
    templateUrl: "itemfilterTemplate.html",
    link: function (scope, element, attrs){
      scope.selectedItemsChangedDir = function(){
        scope.selectedItemsChanged()(scope.selectedItems);  
      }
    }
  }
})

app.controller('MainCtrl', function($scope) {
  $scope.name = 'TARS';

  $scope.selectedItems = ["allItems"];

  $scope.selectedItemsChanged = function(selectedItems1) {
    $scope.selectedItemsReturnedFromDirective = selectedItems1;
  }

  $scope.items = [{
    "id": "allItems",
    "name": "All Items",
    "order": 0
  }, {
    "id": "CaseItem",
    "name": "Case Item",
    "model": "PredefinedModel"
  }, {
    "id": "Application",
    "name": "Application",
    "model": "Bank"
    }]

});

Arbeitsplnkr: http://plnkr.co/edit/BSqx2J1yCY86IJwAnQF1?p=preview

Option 5: Durch ng-Modell und bidirektionale Bindung können Sie übergeordnete Bereichsvariablen aktualisieren. . In einigen Fällen müssen Sie möglicherweise keine übergeordneten Bereichsfunktionen aufrufen.

index.html

<!DOCTYPE html>
<html ng-app="plunker">

  <head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>
    <script>document.write('<base href="' + document.location + '" />');</script>
    <link rel="stylesheet" href="style.css" />
    <script data-require="[email protected]" src="https://code.angularjs.org/1.3.9/angular.js" data-semver="1.3.9"></script>
    <script src="app.js"></script>
  </head>

  <body ng-controller="MainCtrl">
    <p>Hello {{name}}!</p>

    <p> Directive Content</p>
    <sd-items-filter ng-model="selectedItems" selected-items-changed="selectedItemsChanged" items="items"> </sd-items-filter>


    <P style="color:red">Selected Items (in parent controller) set to: {{selectedItems}} </p>

  </body>

</html>

itemfilterTemplate.html

<select ng-model="selectedItems" multiple="multiple" style="height: 200px; width: 250px;" 
 ng-options="item.id as item.name group by item.model for item in items | orderBy:'name'">
  <option>--</option>
</select>

app.js

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

app.directive('sdItemsFilter', function() {
  return {
    restrict: 'E',
    scope: {
      items: '=',
      selectedItems: '=ngModel'
    },
    templateUrl: "itemfilterTemplate.html"
  }
})

app.controller('MainCtrl', function($scope) {
  $scope.name = 'TARS';

  $scope.selectedItems = ["allItems"];

  $scope.items = [{
    "id": "allItems",
    "name": "All Items",
    "order": 0
  }, {
    "id": "CaseItem",
    "name": "Case Item",
    "model": "PredefinedModel"
  }, {
    "id": "Application",
    "name": "Application",
    "model": "Bank"
    }]
});

Arbeitsplnkr: http://plnkr.co/edit/hNui3xgzdTnfcdzljihY?p=preview

Option 6: Durch $watchund$watchCollection Es ist eine bidirektionale Bindung füritems in allen obigen Beispielen würden Elemente in der Direktive auch die Änderungen widerspiegeln, wenn Elemente im übergeordneten Bereich geändert werden.

Wenn Sie andere Attribute oder Objekte aus dem übergeordneten Bereich überwachen möchten, können Sie dies mit $watchund tun$watchCollection wie unten angegeben

html

<!DOCTYPE html>
<html ng-app="plunker">

<head>
  <meta charset="utf-8" />
  <title>AngularJS Plunker</title>
  <script>
    document.write('<base href="' + document.location + '" />');
  </script>
  <link rel="stylesheet" href="style.css" />
  <script data-require="[email protected]" src="https://code.angularjs.org/1.3.9/angular.js" data-semver="1.3.9"></script>
  <script src="app.js"></script>
</head>

<body ng-controller="MainCtrl">
  <p>Hello {{user}}!</p>
  <p>directive is watching name and current item</p>
  <table>
    <tr>
      <td>Id:</td>
      <td>
        <input type="text" ng-model="id" />
      </td>
    </tr>
    <tr>
      <td>Name:</td>
      <td>
        <input type="text" ng-model="name" />
      </td>
    </tr>
    <tr>
      <td>Model:</td>
      <td>
        <input type="text" ng-model="model" />
      </td>
    </tr>
  </table>

  <button style="margin-left:50px" type="buttun" ng-click="addItem()">Add Item</button>

  <p>Directive Contents</p>
  <sd-items-filter ng-model="selectedItems" current-item="currentItem" name="{{name}}" selected-items-changed="selectedItemsChanged" items="items"></sd-items-filter>

  <P style="color:red">Selected Items (in parent controller) set to: {{selectedItems}}</p>
</body>

</html>

Skript app.js

var app = angle.module ('plunker', []);

app.directive('sdItemsFilter', function() {
  return {
    restrict: 'E',
    scope: {
      name: '@',
      currentItem: '=',
      items: '=',
      selectedItems: '=ngModel'
    },
    template: '<select ng-model="selectedItems" multiple="multiple" style="height: 140px; width: 250px;"' +
      'ng-options="item.id as item.name group by item.model for item in items | orderBy:\'name\'">' +
      '<option>--</option> </select>',
    link: function(scope, element, attrs) {
      scope.$watchCollection('currentItem', function() {
        console.log(JSON.stringify(scope.currentItem));
      });
      scope.$watch('name', function() {
        console.log(JSON.stringify(scope.name));
      });
    }
  }
})

 app.controller('MainCtrl', function($scope) {
  $scope.user = 'World';

  $scope.addItem = function() {
    $scope.items.push({
      id: $scope.id,
      name: $scope.name,
      model: $scope.model
    });
    $scope.currentItem = {};
    $scope.currentItem.id = $scope.id;
    $scope.currentItem.name = $scope.name;
    $scope.currentItem.model = $scope.model;
  }

  $scope.selectedItems = ["allItems"];

  $scope.items = [{
    "id": "allItems",
    "name": "All Items",
    "order": 0
  }, {
    "id": "CaseItem",
    "name": "Case Item",
    "model": "PredefinedModel"
  }, {
    "id": "Application",
    "name": "Application",
    "model": "Bank"
  }]
});

Ausführliche Erläuterungen zu Anweisungen finden Sie jederzeit in der AngularJ-Dokumentation.

Yogesh Manware
quelle
10
Er arbeitet hart für seinen Repräsentanten ... so hart für seinen Repräsentanten ... er arbeitet hart für seinen Repräsentanten, also stimmen Sie ihn besser richtig ab.
schlank
7
herabgestuft - wertvolle Informationen in der Antwort sind aufgrund ihrer Länge nicht zugänglich
Wiedergutmachung am
2
Ich beantwortete die Frage mit allen verfügbaren Alternativen mit klarer Trennung. Meiner Meinung nach sind kurze Antworten nicht immer hilfreich, bis Sie ein großes Bild vor sich haben.
Yogesh Manware
@YogeshManware: Es könnte viel verkürzt werden, indem irrelevante Dinge wie Stylesheets weggelassen werden, kein langwieriges Markup verwendet wird, die Beispiele vereinfacht werden, um Dinge wie "Gruppieren nach" usw. nicht zu verwenden. Es wäre auch sehr nützlich, wenn man eine Erklärung dafür gibt jedes Beispiel.
Verdammter
Dies ist kein Grund, abzustimmen. Leute missbrauchen dieses Privileg
Winnemucca
11
 scope: false
 transclude: false

und Sie haben den gleichen Bereich (mit übergeordnetem Element)

$scope.$watch(...

Abhängig von diesen beiden Optionen scope & transclude gibt es viele Möglichkeiten, auf den übergeordneten Bereich zuzugreifen.

Stepan Suworow
quelle
Ja, kurz und bündig und richtig. Sie scheinen jedoch genau denselben Bereich wie das übergeordnete Element zu haben ... was es unmöglich macht, sie im selben Bereich wiederzuverwenden. jsfiddle.net/collindo/xqytH
colllin
2
Oft benötigen wir einen isolierten Bereich, wenn wir wiederverwendbare Komponenten schreiben, daher ist die Lösung nicht so einfach
Yvon Huynh
8

Hier ist ein Trick, den ich einmal verwendet habe: Erstellen Sie eine "Dummy" -Anweisung, um den übergeordneten Bereich zu speichern, und platzieren Sie ihn irgendwo außerhalb der gewünschten Anweisung. Etwas wie:

module.directive('myDirectiveContainer', function () {
    return {
        controller: function ($scope) {
            this.scope = $scope;
        }
    };
});

module.directive('myDirective', function () {
    return {
        require: '^myDirectiveContainer',
        link: function (scope, element, attrs, containerController) {
            // use containerController.scope here...
        }
    };
});

und dann

<div my-directive-container="">
    <div my-directive="">
    </div>
</div>

Vielleicht nicht die anmutigste Lösung, aber sie hat den Job erledigt.

neu
quelle
4

Wenn Sie ES6-Klassen und ControllerAs-Syntax verwenden , müssen Sie etwas anderes tun.

Sehen Sie sich das folgende Snippet an und beachten Sie, dass dies vmder ControllerAsWert des übergeordneten Controllers ist, der im übergeordneten HTML-Code verwendet wird

myApp.directive('name', function() {
  return {
    // no scope definition
    link : function(scope, element, attrs, ngModel) {

        scope.vm.func(...)
Simon H.
quelle
0

Nachdem ich alles versucht hatte, fand ich endlich eine Lösung.

Fügen Sie einfach Folgendes in Ihre Vorlage ein:

{{currentDirective.attr = parentDirective.attr; ''}}

Es schreibt nur das übergeordnete Bereichsattribut / die übergeordnete Variable, auf die Sie zugreifen möchten, in den aktuellen Bereich.

Beachten Sie auch die ; '' am Ende der Anweisung, um sicherzustellen, dass Ihre Vorlage keine Ausgabe enthält. (Angular wertet jede Anweisung aus, gibt jedoch nur die letzte aus.)

Es ist ein bisschen hackig, aber nach ein paar Stunden Versuch und Irrtum macht es den Job.

Jeffrey Roosendaal
quelle