2015-01-05 10 views
5

So auf der Winkel Dokumentations-Website können Sie festlegen, Tobias und JeffWie in einer Richtlinie Link, um den übergeordneten Bereich für den Zugriff auf

angular.module('docsTransclusionExample', []) 
.controller('Controller', ['$scope', function($scope) { 
    $scope.name = 'Tobias'; 
}]) 
.directive('myDialog', function() { 
    return { 
    restrict: 'E', 
    transclude: true, 
    scope: {}, 
    templateUrl: 'my-dialog.html', 
    link: function (scope, element) { 
     scope.name = 'Jeff'; 
    } 
    }; 
}); 

Wenn Sie den Namen zu tun ist {{name}} es sagen wird

The name is Tobias 

Ich versuche, Tobias in der Link-Funktion zuzugreifen. Wie würde ich innerhalb der Link-Funktion den Wert von $ scope.name gleich Tobias erhalten?

scope.$parent.name = 'Jeff'; 
+2

Der '$ parent' ist die Antwort, wie in der Antwort von Ufuk Hacıoğulları, aber zweimal überlegen, wenn Sie * wirklich * wollen, dies zu tun - Es bricht die Verkapselung Ihrer Anweisung. Ein viel besserer Ansatz besteht darin, beliebige Daten als Parameter zu übergeben, z. 'scope: {parentName: '='}' und dann ''. –

+0

Danke Nikos! Die Richtlinie arbeitet derzeit mit dem Geltungsbereich: Falsch und ohne Einschluss. Wie würde ich in diesem Fall auf $ scope.name zugreifen? Wäre es nur $ scope.name? Müsste ich $ scope in den Parameter der Link-Funktion übergeben? –

+0

Das Sehen von 'scope: false'" kommuniziert "mir, dass es einen gemeinsamen/flachen" Namespace "zwischen der Direktive und ihrem Elternteil gibt. In diesem Fall macht es keinen Sinn, zwei "Dinge" namens "name" zu haben - es ist wie "Warum kann ich nicht zwei' var's mit demselben Namen in einer JS Funktion haben ". Was ich versuche zu sagen ist, dass Sie darüber nachdenken sollten, ob dies eine Art Neugestaltung benötigt. –

Antwort

3

Sie $ parent Eigenschaft des Bereichs verwenden müssen. In diesem Fall besteht die einzige Möglichkeit zum direkten Zugriff auf die Eigenschaft des übergeordneten Bereichs darin, den Bereich $parent, Verweis auf das übergeordnete Bereichsobjekt, zu verwenden. Zum Beispiel:

link: function(scope, element) { 
    scope.name = 'Jeff'; 
    scope.parentName = scope.$parent.name; // Tobias 
} 

Dies ist jedoch nicht ideal. Aus diesem Grund ist man flexibler Ansatz betrachten möchten:

<my-dialog name="name"></my-dialog> 

und eine Scope-Konfiguration als definieren:

scope: { 
    parentName: '=name' 
} 
+0

Vielen Dank! Können Sie mir sagen, warum Scope ein Dollarzeichen braucht? Es ist der Umfang statt $ Bereich. Sollte ich dem Parameter ein Dollarzeichen hinzufügen? –

+0

@UXGuy Es braucht es nicht in der Link-Funktion. Ich habe es aktualisiert. –

9

Da der Anwendungsbereich isoliert scope: {}, Richtlinie schafft ein neues Kind -umfang:

+0

Schön! Wie würde ich auf $ scope.name === Tobias zugreifen, wenn scope: false? (Anstelle des Geltungsbereichs: {}, transclude: true) –

+0

Wenn 'scope: false', dann erstellt die Anweisung keinen neuen isolierten Bereich, sondern stattdessen denselben Bereich, in dem sie definiert ist. Es bedeutet, dass Sie auf 'Tobias' als' scope.name' zugreifen können. – dfsq

+0

Kein Dollarzeichen? Setze ich den Bereich noch als Parameter oder $ scope als Parameter? Ich schätze deine Hilfe sehr! –

1

Ich frage mich nur, warum würden Sie so etwas wie dies wollen.

Auf diese Weise erstellen Sie eine Abhängigkeit zwischen dem Controller und der Richtlinie, die nicht existieren sollte.

Wenn Sie Eingabedaten für Ihre Anweisung benötigen, deklarieren Sie sie explizit.

+0

Danke, Alex. Ich glaube nicht, dass die Eingliederung oder der Umfang: {} notwendig sind für das, was ich erreichen möchte. Ich verwende eine bereits erstellte Direktive, die ohne Bereich funktioniert: {}. Ich frage mich nur, wie man auf den Wert $ scope.variable des Controllers in meiner Direktive zugreifen kann. –

+2

Aber genau das ist das "Problem". Wenn Sie über die Direktive auf den übergeordneten Bereich zugreifen, erstellen Sie eine Abhängigkeit. Wenn Sie diese Anweisung in eine andere Seite mit einem anderen Controller verschieben, ist das Verhalten nicht dasselbe. Sie sollten der Direktive immer Daten über Attribute liefern, niemals durch Discovery. Ein anderer Grund dafür ist das Testen. Diese Art von "Dependenzen" zu machen macht es schwierig, Tests in Ihre Richtlinie zu schreiben. – AlexCode

3

Wie Sie transclude:true verwendet haben, können Sie scope:{} weglassen, wenn Sie keine lokalen Variablen haben. Putting scope:{} macht keinen Sinn.

so die Erklärung wie folgt

angular.module('docsTransclusionExample', []) 
.controller('Controller', ['$scope', function($scope) { 
    $scope.name = 'Tobias'; 
}]) 
.directive('myDialog', function() { 
    return { 
    restrict: 'E', 
    transclude: true, 
    templateUrl: 'my-dialog.html', 
    link: function (scope, element) { 
     // scope.name = 'Jeff'; 
     // if name is in your parent scope, you should be able to get it here 
     console.log(scope.name); 
    } 
    }; 
}); 

bei der Vorlage Wenn Sie Sie ng-transclude Richtlinie verwendet wurde, sehen aussehen würde, bedeutet dies in Vorlage, wo der Wille des übergeordneten Bereich Variablen dort verwendet werden. Ich hoffe es macht Sinn.

+0

Vielen Dank! Ich bin mir nicht sicher, ob die Transkription überhaupt notwendig ist, aber Sie machen einen guten Punkt! Ich versuchte dies mit der Hoffnung, dass es mein Problem beheben würde, und bekomme "kann SomeProperty Wert von undefined nicht" in der Konsole lesen. Ich habe Spielraum: falsch und denke, ich mache alles, was du geschrieben hast. Ich werde überprüfen ... –

+0

* Ich bin mir nicht sicher, dass die Einschreibung notwendig ist, weil ich es noch nicht vollständig verstehe und die Richtlinie funktionierte ohne Einschluss der Deklaration –

+0

wenn Sie transclude verwenden, lassen Sie einfach den Bereich aus (nicht falsch, nur don tu es nicht). transclude bringt den übergeordneten Bereich in die Direktive. Wenn Sie an die 'ng-repeat'-Direktive denken, die Ihre Direktiven/Templates umschließt, aber die Werte, die Sie im 'ng-repeat'-Bereich haben, mitbringt. – Kamrul

3

Sie können es über $ parent wie diese:

link: function (scope, element) { 
    scope.name = 'Jeff'; 
    console.log(scope.name); 
    console.log(scope.$parent.name); 
} 
Verwandte Themen