2016-02-19 7 views
7

Ich versuche eine benutzerdefinierte Direktive zu erstellen, die es mir erlaubt, Fragen in der Umfrage anzuzeigen. Da ich mehrere Arten von Fragen habe, habe ich darüber nachgedacht, einzelne Direktiven zu erstellen und ihre Vorlage je nach Fragentyp zu ändern.Conti-Vorlage - Controller 'mdRadioGroup', benötigt von Direktive 'mdRadioButton', kann nicht gefunden werden

meine Richtlinie:

directive('question', function($compile) { 
    var combo = '<div>COMBO - {{content.text}}</div>'; 
    var radio = [ 
    '<div>RADIO - {{content.text}}<br/>', 
    '<md-radio-group layout="row" ng-model="content.answer">', 
    '<md-radio-button ng-repeat="a in content.answers track by $index" ng-value="a.text" class="md-primary">{{a.text}}</md-radio-button>', 
    '</md-radio-group>', 
    '</div>' 
    ].join(''); 
    var input = [ 
    '<div>INPUT - {{content.text}}<br/>', 
    '<md-input-container>', 
    '<input type="text" ng-model="content.answer" aria-label="{{content.text}}" required md-maxlength="10">', 
    '</md-input-container>', 
    '</div>' 
    ].join(''); 

    var getTemplate = function(contentType) { 
    var template = ''; 

    switch (contentType) { 
     case 'combo': 
     template = combo; 
     break; 
     case 'radio': 
     template = radio; 
     break; 
     case 'input': 
     template = input; 
     break; 
    } 

    return template; 
    } 

    var linker = function(scope, element, attrs) { 

    scope.$watch('content', function() { 
     element.html(getTemplate(scope.content.type)) 
     $compile(element.contents())(scope); 

    }); 
    } 

    return { 
    //require: ['^^?mdRadioGroup','^^?mdRadioButton'], 
    restrict: "E", 
    link: linker, 
    scope: { 
     content: '=' 
    } 
    }; 
}) 

In meinem Haupt-Controller habe ich Liste von Fragen und nach Button Ich gründe aktuelle Frage, die zuweisen meiner Richtlinie ist.

Alles funktioniert für erste Fragen in Ordnung, aber nachdem ich aktuelle Frage an Radio Typen eingestellt bekomme ich diesen Fehler:

Error: [$compile:ctreq] Controller 'mdRadioGroup', required by directive 'mdRadioButton', can't be found!

ich required meine Direktive hinzugefügt, wie unten habe versucht, aber es kann nicht geholfen hat .

Ich kann nicht herausfinden, was los ist, weil ich noch zu eckig bin.

Ich habe Plunker erstellt mein Problem zu zeigen: http://plnkr.co/edit/t0HJY51Mxg3wvvWrBQgv?p=preview

Schritte um diesen Fehler zu reproduzieren:

  1. öffnen Plunker
  2. Klicken Sie Next Taste zweimal (navigieren Frage 3)
  3. Siehe Fehler in der Konsole

EDIT:
Ich habe meinen Plunker bearbeitet, damit mein Fragenmodell sichtbar ist. Ich bin in der Lage, Antworten auszuwählen, auch in Fragen, die Fehler-Fragen-Modell zu aktualisieren ist. Aber immer noch bekomme ich Fehler, wenn ich zu Frage 3 gehe.

Antwort

3

Ich würde einfach eine Basis-Anweisung erweitern, und dann haben Sie eine spezielle mit verschiedenen Direktiven Namen auch.

// <div b></div> 
ui.directive('a', ...) 
myApp.directive('b', function(aDirective){ 
    return angular.extend({}, aDirective[0], { templateUrl: 'newTemplate.html' }); 
}); 

-Code genommen von https://github.com/angular/angular.js/wiki/Understanding-Directives#specialized-the-directive-configuration

+0

Vielen Dank für diesen Vorschlag, aber könnten Sie mir auch helfen, Fehler zu entfernen, die ich gerade bekomme? – Misiu

+0

Das ist eine gute Frage. Der erste, den ich bemerkte, ist, dass du kein ng-Modell auf deiner 'md-radio-group' hast. – Iamisti

+0

Ich habe' ng-model' hinzugefügt, aber es hat nicht geholfen. – Misiu

2

ich ein wenig mit Ihrem Code gespielt und stellen fest, dass der Grund, warum der Fehler aufgetreten ist, weil die dritte Frage mehr Antworten bekam als die zweite, also, wenn Sie die mdRadioGroup erstellen das erste Mal definiert es 4 $ Index Antworten und später für Frage 3 geht es mit 6 Antworten aus dem Schrank ... Also eine nicht elegante Lösung ist es, so viele $ Index als die maximalen Antworten auf jede Frage, das erste Mal, zu erstellen nur die mit Text ...

.directive('question', function($compile) { 
var combo = '<div>COMBO - {{content.text}}</div>'; 
var radio = [ 
'<div>RADIO - {{content.text}}<br/>', 
'<md-radio-group layout="row">', 
'<md-radio-button ng-repeat="a in content.answers track by $index" ng-show={{a.text!=""}} value="{{a.text}}" class="md-primary">{{a.text}}</md-radio-button>', 
'</md-radio-group>', 
'</div>' 
].join(''); 
var input = [ 
'<div>INPUT - {{content.text}}<br/>', 
'<md-input-container>', 
'<input type="text" ng-model="color" aria-label="{{content.text}}" required md-maxlength="10">', 
'</md-input-container>', 
'</div>' 
].join(''); 

var getTemplate = function(contentType) { 
var template = ''; 

switch (contentType) { 
    case 'combo': 
    template = combo; 
    break; 
    case 'radio': 
    template = radio; 
    break; 
    case 'input': 
    template = input; 
    break; 
} 

return template; 
} 

dann Fragen ändern Sie die maximale Anzahl der Antworten in allen Fragen jedes Mal haben:

$scope.questions = [{ 
type: 'radio', 
text: 'Question 1', 
answers: [{ 
    text: '1A' 
}, { 
    text: '1B' 
}, { 
    text: '1C' 
}, { 
    text: '' 
}, { 
    text: '' 
}, { 
    text: '' 
}, { 
    text: '' 
}] 
}, { 
type: 'input', 
text: 'Question 2', 
answers: [{ 
    text: '2A' 
}, { 
    text: '2B' 
}, { 
    text: '2C' 
}, { 
    text: '' 
}, { 
    text: '' 
}, { 
    text: '' 
}, { 
    text: '' 
}] 
}, { 
type: 'radio', 
text: 'Question 3', 
answers: [{ 
    text: '3A' 
}, { 
    text: '3B' 
}, { 
    text: '3C' 
}, { 
    text: '3D' 
}, { 
    text: '' 
}, { 
    text: '' 
}, { 
    text: '' 
}] 
}, { 
type: 'combo', 
text: 'Question 4', 
answers: [{ 
    text: '4A' 
}, { 
    text: '4B' 
}, { 
    text: '' 
}, { 
    text: '' 
}, { 
    text: '' 
}, { 
    text: '' 
}, { 
    text: '' 
}] 
}]; 

Der Rest des Codes gleich ist. Wie ich schon sagte, keine elegante und sicher gibt es bessere Möglichkeiten, aber könnte eine Lösung für jetzt sein ...

+0

benutze Danke für Hilfe. Ich denke, es ist etwas merkwürdiges Verhalten, weil ich Vorlage jedes Mal kompiliere, wenn ich Frage ändere. Ich werde diese Frage offen lassen und so schnell wie möglich Bounty starten. – Misiu

3

Working Demo

Es besteht keine Notwendigkeit zu schaffen und eine Richtlinie für Ihre Anforderung zu verwenden.

Sie können nur Winkelschablonen und ng-include mit Bedingung verwenden.

erstellen Sie können nur drei Vorlagen (jeweils für Combo, Radio und Eingang) auf Ihrer Seite wie diese,

<script type="text/ng-template" id="combo"> 
    <div>COMBO - {{content.text}}</div> 
</script> 

Und sind diese Vorlagen in einem div ng-include verwenden.

<!-- Include question template based on the question --> 
<div ng-include="getQuestionTemplate(question)"> 

Hier getQuestionTemplate() wird die ID der Vorlage zurück, die in diesem div aufgenommen werden sollte.

// return id of the template to be included on the html 
$scope.getQuestionTemplate = function(content){ 
    if(content.type == "combo"){ 
     return 'combo'; 
    } 
    else if (content.type == "radio"){ 
     return 'radio'; 
    } 
    else{ 
     return 'input'; 
    } 
} 

Das ist alles. Du bist fertig.

Zögern Sie bitte nicht, mich zu fragen.

+0

Vielen Dank für die Antwort. Es ist komplizierter. Ich würde gerne Sub-Direktiven in meiner Direktive verwenden, weil ich für jeden Fragetyp eine andere Logik benötige, zum Beispiel eine Validierung. Für eine einfache Texteingabe möchte ich prüfen, ob der eingegebene Text der richtigen Antwort entspricht, die ich erhalten möchte, für Checkboxen muss ich prüfen, ob nur die richtigen ausgewählt sind. Ich denke, diese Modularität wird mir in Zukunft helfen. Hier ist Plunker zeigt meinen zweiten Ansatz: http://plnkr.co/edit/fq6nTXGYBT8oJSkvOFIE?p=preview – Misiu

+0

@ Misiu, Klingt gut. Entschuldige, dass ich dich irreführe. Geh mit deinem derzeitigen Ansatz. Alles Gute !!! :) –

+0

Ihre Lösung funktioniert gut ohne Fehler, aber ich würde wirklich gerne diese Inside-Direktive verwenden. Irgendwelche Ideen, warum ich diesen Fehler bekomme? – Misiu