2016-02-19 9 views
7

Próbuję stworzyć niestandardową dyrektywę, która pozwoli mi wyświetlać pytania w ankiecie. Ponieważ mam wiele typów pytań, pomyślałem o stworzeniu pojedynczej dyrektywy i zmianie jej szablonu na podstawie typu pytania.Szablon warunkowy - kontroler "mdRadioGroup", wymagany przez dyrektywę "mdRadioButton", nie można znaleźć

mój dyrektywy:

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: '=' 
    } 
    }; 
}) 

Wewnątrz mojego głównego kontrolera Mam listę pytań i po kliknięciu przycisku mam ustawienie aktualnego pytanie, który jest przypisany do mojego dyrektywy.

Wszystko działa dobrze dla pierwszych pytań, ale po tym, jak ustawić aktualną pytanie typu urządzenia radiowego otrzymuję ten błąd:

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

próbowałam dodanie required do mojego dyrektywy jak poniżej, ale to nie pomogło .

require: ['^mdRadioGroup'], 

Nie mogę zrozumieć, co się dzieje, ponieważ wciąż jestem nowy w kanciastości.

Utworzyłem Plunker pokazać mój problem: http://plnkr.co/edit/t0HJY51Mxg3wvvWrBQgv?p=preview

kroki, aby odtworzyć ten błąd:

  1. Otwórz Plunker
  2. Kliknij Next przycisk dwa razy, aby przejść do (pytanie 3)
  3. Zobacz błąd w konsoli

EDYCJA:
Edytowałem mój Plunker, więc mój model pytań jest widoczny. Jestem w stanie wybrać odpowiedzi, nawet w przypadku pytań, które powodują aktualizację modelu pytań o błąd. Ale nadal dostaję błąd podczas zadawania pytania 3.

Odpowiedz

3

Po prostu po prostu rozszerzę dyrektywę bazową, a następnie będę miał wyspecjalizowane te o różnych nazwach dyrektyw.

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

Kod wzięty z https://github.com/angular/angular.js/wiki/Understanding-Directives#specialized-the-directive-configuration

+0

Dziękuję za tę propozycję, ale czy mógłbyś mi również pomóc w usunięciu błędu, który dostaję właśnie teraz? – Misiu

+0

To dobre pytanie. Pierwszą rzeczą, którą zauważyłem jest to, że nie masz ng-modelu na swojej 'md-radio-group' – Iamisti

+0

Dodałem' ng-model', ale to nie pomogło. – Misiu

2

grałem trochę z kodem i okaże się, że powodem, dla którego wystąpił błąd dlatego 3rd pytanie ma więcej odpowiedzi niż 2, więc podczas tworzenia mdRadioGroup po raz pierwszy definiuje 4-indeksu odpowiedzi, a później na pytanie 3 wychodzi poza związaną z 6 odpowiedziami ... Więc nie eleganckim rozwiązaniem jest utworzenie tyle $ index jako max odpowiedzi na każde pytanie, po raz pierwszy, pokaż tylko te z tekstem ...

.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; 
} 

następnie zmienić zapytanie mieć Maxa ilość odpowiedzi za każdym razem, we wszystkich pytań:

$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: '' 
}] 
}]; 

Reszta kodu jest taka sama. Jak już mówiłem, brak elegancji i na pewno są lepsze opcje, ale może być rozwiązaniem na razie ...

+0

Dziękuję za pomoc. Myślę, że to dziwne zachowanie, ponieważ kompiluję szablon za każdym razem, gdy zmieniam pytanie. Pozostawię to pytanie otwarte i zacznę hojność tak szybko, jak tylko będę mogła. – Misiu

3

Working Demo

Nie ma potrzeby, aby tworzyć i stosować dyrektywę do Państwa wymagań.

Możesz po prostu użyć szablonów kątowych i ng-include pod warunkiem.

można po prostu stworzyć trzy szablony (każdy dla kombi, radio i wejście) na swojej stronie jak ta,

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

i obejmują te szablony w div za pomocą ng-include.

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

Tutaj getQuestionTemplate() zwróci identyfikator szablonu, które powinny być uwzględnione w tym div.

// 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'; 
    } 
} 

To wszystko. Jesteś skończony.

Proszę, zadaj mi jakąkolwiek wątpliwość.

+0

Dziękuję bardzo za odpowiedź. To jest bardziej skomplikowane. Chciałbym użyć pod dyrektyw w mojej dyrektywie, ponieważ potrzebuję innej logiki dla każdego rodzaju pytania, na przykład sprawdzania poprawności. Dla prostego wprowadzania tekstu chciałbym sprawdzić, czy wpisany tekst jest prawidłową odpowiedzią, którą chciałbym uzyskać, w przypadku pól wyboru muszę sprawdzić, czy wybrano tylko poprawne. Myślę, że ten rodzaj modułowości pomoże mi w przyszłości. Oto Plunker pokazujący moje drugie podejście: http://plnkr.co/edit/fq6nTXGYBT8oJSkvOFIE?p=preview – Misiu

+0

@Misiu, Brzmi nieźle. Przepraszam, że wprowadzam cię w błąd. Idź z obecnym podejściem. Wszystkiego najlepszego !!! :) –

+0

Twoje rozwiązanie działa poprawnie bez błędów, ale naprawdę chciałbym użyć tej wewnętrznej dyrektywy. Jakieś pomysły, dlaczego dostaję tego błędu? – Misiu

Powiązane problemy