2016-02-19 9 views
7

Sto provando a creare una direttiva personalizzata che consenta di visualizzare le domande nel sondaggio. Poiché ho diversi tipi di domande, ho pensato di creare una direttiva singola e di cambiarne il modello in base al tipo di domanda.Modello contidionale - Impossibile trovare il controller 'mdRadioGroup' richiesto dalla direttiva 'mdRadioButton'

mia direttiva:

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

Dentro il mio controller principale ho lista di domande e dopo il pulsante cliccando Sto installando domanda attuale che è assegnare alla mia direttiva.

Tutto funziona bene per le prime domande, ma dopo essere stata impostata domanda attuale tipo di radio ottengo questo errore:

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

Ho provato ad aggiungere al mio required direttiva come sotto, ma non ha aiutato .

require: ['^mdRadioGroup'], 

Non riesco a capire che cosa sta succedendo, perché sono ancora nuovo di spigoloso.

ho creato Plunker per mostrare il mio problema: http://plnkr.co/edit/t0HJY51Mxg3wvvWrBQgv?p=preview

passaggi per riprodurre questo errore:

  1. Aprire Plunker
  2. Clicca Next pulsante due volte (per navigare alla domanda 3)
  3. Vedere errore nella console

EDIT:
Ho modificato il mio Plunker in modo che il mio modello di domande sia visibile. Sono in grado di selezionare le risposte, anche nelle domande che sollevano il modello di domande di errore che si sta aggiornando. Ma ho ancora errore quando si passa alla domanda 3.

risposta

3

Vorrei semplicemente estendere una direttiva di base, e quindi avere uno specializzato con nomi di direttive differenti.

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

codice preso dal https://github.com/angular/angular.js/wiki/Understanding-Directives#specialized-the-directive-configuration

+0

Grazie per questa proposta, ma potresti anche aiutarmi a rimuovere l'errore che sto ottenendo in questo momento? – Misiu

+0

Questa è una buona domanda. Il primo che ho notato è che non si ha un modello ng sul 'md-radio-group' – Iamisti

+0

Ho aggiunto' ng-model' ma non è stato d'aiuto. – Misiu

2

ho giocato un po 'con il codice e scoprire che, il motivo per cui si è verificato l'errore è perché la terza domanda ha più risposte rispetto al 2 °, in modo che quando si crea il mdRadioGroup la prima volta che definisce 4 risposte indice $ e in seguito per la domanda 3 esce fuori con 6 risposte ... Quindi una soluzione non elegante è creare un numero di $ qualsiasi come la risposta massima a qualsiasi domanda, la prima volta, mostra solo quelli con testo ...

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

quindi modificare le domande per avere l'importo massimo di risposte ogni volta che in tutte le questioni:

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

Il resto del codice è lo stesso. Come ho detto prima, non elegante e di sicuro ci sono opzioni migliori, ma potrebbe essere una soluzione per ora ...

+0

Grazie per l'aiuto. Penso che sia un po 'strano comportamento, perché sto compilando il modello ogni volta che cambio la domanda. Lascerò questa domanda aperta e comincerò a lanciarmi il più velocemente possibile. – Misiu

3

Working Demo

Non v'è alcuna necessità di creare e utilizzare una direttiva per il vostro requisito.

È possibile utilizzare solo modelli angolari e ng-include con condizioni.

Si può solo creare tre modelli (ciascuno per combo, radio e ingresso) sulla vostra pagina come questa,

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

E includere questi modelli in un div con ng-include.

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

Qui, getQuestionTemplate() restituirà l'id del modello che dovrebbe essere incluso in questo 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'; 
    } 
} 

Questo è tutto. Hai fatto.

Non esitate a chiedermi qualsiasi dubbio su questo.

+0

Grazie mille per la risposta. È più complicato Mi piacerebbe utilizzare le sotto-direttive nella mia direttiva, perché ho bisogno di una logica diversa per ogni tipo di domanda, ad esempio la convalida. Per un semplice inserimento del testo vorrei verificare se il testo inserito è uguale alla risposta corretta che vorrei ottenere, per le caselle che devo controllare se sono selezionate solo corrette. Penso che questo tipo di modularità mi aiuterà in futuro. Ecco Plunker che mostra il mio secondo approccio: http://plnkr.co/edit/fq6nTXGYBT8oJSkvOFIE?p=preview – Misiu

+0

@Misiu, Suona bene. Mi dispiace di ingannarti. Vai con il tuo approccio attuale. Ti auguro il meglio !!! :) –

+0

La tua soluzione funziona bene senza errori, ma mi piacerebbe davvero usare quella direttiva interna. Qualche idea per cui sto ricevendo quell'errore? – Misiu

Problemi correlati