2013-03-31 17 views
5

Ich möchte ein Modell in einer Vorlage aliasieren, so dass dieselbe Vorlage für verschiedene Modelle wiederverwendet werden kann. Zum Beispiel in dem folgende Modell:Aliasing eines Modells in ngtemplate

member = { 

    name: "Member1", 
    children:[ 
    { 
     name:"Child1" 
    }, 
    { 
     name:"Child2" 
    } 
    ] 
} 

beide „Mitglied“ und „Kinder“ haben „Namen“ Eigenschaft. Ich möchte also eine einzige Vorlage erstellen, die diese "name" -Eigenschaft manipuliert. Ich konnte dies mit Hilfe dieser Frage erreichen:

Bind ngInclude to different models

Wie vorgeschlagen, ich habe eine Richtlinie erstellt, wie:

app.directive('member', function(){ 
return { 
    restrict: 'A', 
    template: "{{prefix}}<input type='text' ng-model='member.name'>", 
    scope: { 
     member: "=" 
    } 
}; 
}); 

Nach ist die Verwendung dieser Richtlinie:

Ich konnte die Wiederverwendung der Vorlage erreichen, aber da ich "scope" in meiner Direktive verwende, hat dies eine Isola erstellt ted-Bereich, der nicht auf eine Eigenschaft des Controller-Bereichs zugreifen kann. So für den Controller:

app.controller('MemberCtrl', function($scope){ 
$scope.member = { 

    name: "Member1", 
    children:[ 
    { 
     name:"Child1" 
    }, 
    { 
     name:"Child2" 
    } 
    ] 
}; 

    $scope.prefix = "Mr."; 
}); 

die Vorlage in der Richtlinie nicht in der Lage, die „Präfix“ Eigenschaft zuzugreifen. Im Anschluss an die jsfiddle:

http://jsfiddle.net/vaibhavgupta007/mVBaC/1/

Was das Problem in dieser sein könnte?

bearbeiten

ich auch $ parent das Präfix zugreifen können. Aber ist das ein sauberer Ansatz?

Antwort

1

Definieren Sie einfach 'Präfix' als isolierte Bereichsvariable in Ihrem Objekt der Richtliniendefinition und verweisen Sie es in Elementattributen.

app.directive('member', function(){ 
return { 
    restrict: 'A', 
    template: "{{prefix}}<input type='text' ng-model='member.name'>", 
    scope: { 
     member: "=", 
     prefix: "=" 
    } 
}; 
}); 

 

<div ng-controller="MemberCtrl"> 
    {{member | json}} 
    <div member="member" prefix="prefix"></div> 
    <div member="member.children[0]" prefix="prefix"></div> 
</div> 

Fiddle

+0

Ja, das ist ein Ansatz, aber wie stelle ich den Controller-Bereich der Direktive zur Verfügung, so dass er auf einige Hilfsfunktionen zugreifen kann. Wenn der Controller zum Beispiel eine Funktion namens "joinNameWithPrefix" im Bereich hat, kann die Direktive nicht darauf zugreifen. – Vaibhav

+0

In diesem Fall können Sie den Bereich "scope" vollständig aus dem Objekt der Definition der Anweisung auslassen, und die Anweisung erstellt keinen isolierten Bereich, sondern verwendet standardmäßig den übergeordneten Bereich. – Stewie

+0

Aber dann kann ich kein Aliasing erreichen. Sieht aus wie ein Huhn und Ei Problem für mich ... :) Ich denke, Aliasing wird in angularjs nicht mit einem direkten Weg unterstützt. Ich werde $ Eltern in der Vorlage verwenden müssen. – Vaibhav

0

Um eine Richtlinie Anwendungsbereich Eigenschaft auf verschiedene Controller-Eigenschaften zu binden (zB member und member.children[0]) zur Verwendung in einer generischen Vorlage, ich glaube, Sie muss die isolate scope-Syntax verwenden (wie Sie bereits festgestellt haben).

Sobald Sie gehen Sie die „isolieren Umfang Straße“, werden Sie alle Controller-Eigenschaften und Funktionen angeben müssen, dass Ihre Richtlinie Zugriff auf als zusätzliche Attribute benötigt:

<div member="member" prefix="{{prefix}}" join-fn="joinNameWithPrefix(someName)"></div> 

Dann in Ihrer Richtlinie:

template: "{{prefix}}<input type='text' ng-model='member.name'>" 
    + "<br>fn result={{ joinFn({someName: member.name}) }}", 
scope: { 
    member: "=", 
    prefix: '@', 
    joinFn: '&' 
}, 

Fiddle

Verwenden = für zwei-Wege-Datenbindung, @ für Einweg-Strings und & für Einwegausdrücke.