Vorrei creare un wrapper per il mio campo di input con un suggerimento di input-help all'interno di esso.AngularJS: Trascludi un singolo elemento di input in un modello di direttiva senza utilizzare un contenitore
Sto usando angular 1.0.7, se è significativo.
Sto utilizzando transclude: true, insieme all'ambito isolato per consentire errori in diversi campi contemporaneamente e mantenere il riferimento del modello ng all'ambito $ esterno.
Il problema:
quando uso questa direttiva sul l'elemento di input, l'elemento di input non clone ('Transclude') nel modello direttiva.
Come risultato, ottengo un elemento div vuoto nel DOM, con un attributo ng-transclude.
Plunk: http://plnkr.co/edit/vFB9ih6x2NBmwhAes3Qh?p=preview
codice:
<input data-my-validate-input data-value-required="true" type="password" class="loginItem" placeholder="Password" name="password" data-ng-model="formData.password" data-display-name="Password">
Tuttavia quando ho avvolgere questo elemento di input in un arco o di div, l'elemento di input bambino è trasceso bene, ma poi non ho ricevuto il riferimento al modello ng esterno corretto (ctrl) alla direttiva.
<span data-my-validate-input data-value-required="true" data-display-name="Password">
<input type="password" class="loginItem" placeholder="Password" name="password" data-ng-model="formData.password" >
</span>
codice completo (la logica all'interno della funzione di collegamento non è rilevante per il problema, ma ho preferito postare il mio codice completo)
directive('myValidateInput', function() {
return {
require: 'ngModel',
restrict: 'A',
transclude: true,
scope: {
displayName: '@',
valueRequired: '@',
maxLength: '@',
minLength: '@',
minLetters: '@',
minNumbers: '@'
},
template: '<div class="validationContainer">\
<div ng-transclude></div>\
<div class="input-help">\
<h4>{{fieldErrorDisplay}}</h4>\
<ul>\
<li data-ng-repeat="rule in requirementSpec" ng-class="rule.class">\
{{rule.msg}}\
</li>\
</ul>\
</div>\
</div>',
replace: true,
link: function(scope, elm, attrs, ctrl) {
var validator = function(viewValue){
if(scope.valueRequired && viewValue.length == 0 && (!scope.maxLength && !scope.minLength && !scope.minLetters && !scope.minNumbers)){
scope.valid = false;
scope.fieldErrorDisplay = scope.fieldName + ' is required';
}
else{
scope.fieldErrorDisplay = scope.fieldName + ' must meet the following requirements: ';
scope.requirementSpec = [];
if(scope.minLength){
var itemValidity = viewValue.length >= scope.minLength;
scope.valid = !itemValidity ? false : scope.valid;
var item = {
'msg' : 'Must be at least ' + scope.minLength + ' characters long',
'class' : itemValidity ? 'valid' : undefined
};
scope.requirementSpec[nameStr].push(item);
}
else if(scope.valueRequired){
var itemValidity = viewValue && viewValue.length >= 1;
scope.valid = !itemValidity ? false : scope.valid;
var item = {
'msg' : 'This field must be filled',
'class' : itemValidity ? 'valid' : undefined
};
scope.requirementSpec[nameStr].push(item);
}
if(scope.maxLength){
var itemValidity = viewValue.length <= scope.maxLength;
scope.valid = !itemValidity ? false : scope.valid;
var item = {
'msg' : 'Must be ' + scope.maxLength + ' characters long at most ',
'class' : itemValidity ? 'valid' : undefined
};
scope.requirementSpec[nameStr].push(item);
}
if(scope.minLetters){
var itemValidity = (viewValue && /[A-z]/.test(viewValue));
scope.valid = !itemValidity ? false : scope.valid;
var item = {
'msg' : 'Must contain at least ' + scope.minLetters + ' letters',
'class' : itemValidity ? 'valid' : undefined
};
scope.requirementSpec[nameStr].push(item);
}
if(attrs.minNumbers){
var itemValidity = (viewValue && /\d/.test(viewValue));
scope.valid = !itemValidity ? false : scope.valid;
var item = {
'msg' : 'Must contain at least' + attrs.minNumbers + ' numbers',
'class' : itemValidity ? 'valid' : undefined
};
scope.requirementSpec[nameStr].push(item);
}
}
if(scope.valid) {
ctrl.$setValidity(nameStr, true);
return viewValue;
} else {
ctrl.$setValidity(nameStr, false);
return undefined;
}
}
scope.requirementSpec = {};
ctrl.$parsers.unshift(function(viewValue) {
return validator(viewValue);
});
ctrl.$formatters.unshift(function(viewValue) {
// var before = scope.$eval(attrs.validateBefore);
if(viewValue && viewValue != "" && viewValue.length > 0)
return validator(viewValue);
});
});
}
});
puoi pubblicare il modello HTML che hai usato, sarà bello vedere il tuo problema in Fiddle/Plunker. Grazie –
Plunk aggiunto: http://plnkr.co/edit/vFB9ih6x2NBmwhAes3Qh?p=preview –