Déclaration dans un scope isolé
Bonjour,
J'explore en ce moment les possibilités des directives d'angularJS et je suis tombé sur un os, si vous pouviez m'éclairer sur certaines logiques de programmations qui, apparemment, me font défaut, je vous en serais extrêmement reconnaissant.
Voici mon template, un formulaire de connexion :
Code:
1 2 3 4 5 6
| <login-form class="container-fluid navbar-form navbar-left" ng-submit="submit()">
<checked-input name="username" type="text" placeholder="login"></checked-input>
<checked-input name="password" type="password" placeholder="password"></checked-input>
<button type="submit" class="btn btn-default">log in</button>
</login-form> |
Le checked-input est une directive correspondant à un input avec icône de confirmation style bootstrap ( un exemple sur l'image ci-après ) dont voici le template :
Code:
1 2 3 4 5
| <div class="form-group has-feedback">
<label class="control-label" ng-class="{'sr-only': !label}">{{label}}</label>
<input type="{{type}}" name="{{name}}" placeholder="{{placeholder}}" class="form-control" ng-model="chkInput.value">
<span class="glyphicon form-control-feedback"></span>
</div> |
http://nsa34.casimages.com/img/2014/...0716671185.png
Avant de parler des app.directive, je vous fait part de ma logique du code :
L'idée est qu'en insérant une directive checked-input dans une page, les attributs qu'on a définit dans l'élément checked-input se répartissent sur les éléments enfants (par exemple, au-dessus j'ai crée un checked-input name="username", l'input aura donc le nom username.
Pour la mise en place simple de ce fonctionnement, j'ai opté pour un scope isolé :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| app.directive('loginForm', function() {
return {
restrict: 'E',
replace: true,
transclude: true,
template: '<form ng-transclude></form>',
controller: ['$scope', '$http', function($scope, $http) {
$scope.submit = function() {
$http.post(...
// pas vraiment nécessaire d'embrouiller mon code ici,
// seulement que j'utilise $scope.username.status(state) et $scope.password.status(state)
...)
}
}]
}
});
app.directive('checkedInput', function() {
return {
restrict: 'E',
replace: true,
scope: {
chkInput: '=name',
type: '@',
name: '@',
placeholder: '@',
label: '@'
},
templateUrl: 'partials/chkInput.html',
controller: ['$scope', function($scope) {
$scope.chkInput = {
value: null,
parentStyle: null,
iconStyle: null,
status: function(state) {
if (state !== undefined) {
this.parentStyle = state ? 'has-success' : 'has-error';
this.iconStyle = state ? 'glyphicon-ok' : 'glyphicon-remove';
}
else {
this.parentStyle = null;
this.iconStyle = null
}
}
};
}]
}
}); |
Ainsi, dans mon scope de la première instance de <checked-input> (name = "username"), $scope.chkInput est lié par data-binding au scope du <login-form> : $scope.username.
L'idée est donc de déclarer $scope.username et $scope.password en déclarant $scope.chkInput dans la directive de l'élément enfant (car il est lié par databinding).
Problème : Ce code ne fonctionne pas, pour la simple et bonne raison que le two-way-dataBinding permet de faire tout cela, excepté faire des déclarations dans l'élément enfant (<checked-input>). Je ne peux donc pas déclarer $scope.username de la directive <login-form> en déclarant $scope.chkInput de la directive <checked-input>.
Solutions explorées :
- Comme dans la doc d'angular : déclarer l'objet dans l'élement parent, mais pour des raisons évidentes de structure du code, c'est hors-propos.
- Même si la directive est dans un scope isolé, le scope reste tout de même un enfant du scope de loginForm. On devrait donc pouvoir y accéder via $scope.$parent[$scope.name] = {..., mais pour des raisons qui m'échappent, celà ne fonctionne pas et cette objet n'est pas créé dans le scope parent.
- Créer un contructeur de cet objet dans la directive enfant et y accéder en ajoutant require: '^checkedInput' dans la directive loginForm, j'aimerais éviter si possible.
Je vous remercie d'avance si vous pouvez m'aider, je planche là-dessus depuis 2-3 jours et je vois vraiment pas comment m'en sortir :calim2:.
A+ ;)
Kaari
PS: si vous êtes d'attaque pour m'aider mais que mes faibles compétences linguistiques ne m'ont pas permis de vous expliquer clairement mon problème, je vous prie de m'en excuser et de ne pas hésiter à me dire que je me suis très mal expliqué et que vous ne comprenez rien à mon charabia :mrgreen:.