web-dev-qa-db-fra.com

composant angulaire 1.5/valeur par défaut pour @ binding

Existe-t-il un moyen de spécifier la valeur par défaut pour une liaison @ d'un composant.

J'ai vu des instructions sur la marche à suivre avec directive: Comment définir une valeur par défaut dans un champ d'application de la directive Angular?

Mais le composant ne supporte pas la fonction de compilation.

Donc, j'ai composant comme ça:

{
  name: 'myPad',
  bindings   : {layout: '@'}
}

Je souhaite éviter aux utilisateurs de mon composant de spécifier la valeur de l'attribut "layout". Donc ça:

<my-pad>...</my-pad>

au lieu de cela:

<my-pad layout="column">...</my-pad>

Et ... cet attribut 'layout' est supposé être consommé par JS de matériau angulaire que m utilise, il doit donc être lié avant le rendu du DOM (pour que le matériau JS puisse le récupérer et ajouter les classes correspondantes à l'élément).

mise à jour, quelques captures d'écran pour clarifier la situation:

Définition du composant:

{
  name : 'workspacePad',
  config : {
    templateUrl: 'src/workspace/components/pad/template.html',
    controller : controller,
    bindings   : {
      actions: '<', actionTriggered: '&', workspaces: '<', title: '@',
      flex: '@', layout: '@'
    },
    transclude: {
      'workspaceContent': '?workspaceContent'
    }
  }
}

Utilisation du composant:

<workspace-pad flex layout="column" title="Survey List" actions="$ctrl.actions"
  action-triggered="$ctrl.performAction(action)">
  <workspace-content>
    <div flex style="padding-left: 20px; padding-right: 20px; ">
      <p>test test</p>
    </div>
  </workspace-content>
</workspace-pad>

Je veux faire que "flex" et "layout" dans la deuxième capture d'écran (utilisation) optionnels.


METTRE À JOUR

Ma "solution" pour avoir ceci dans le constructeur de mon composant:

this.$postLink = function() {
  $element.attr("flex", "100");
  $element.attr("layout", "column");
  $element.addClass("layout-column");
  $element.addClass("flex-100");
}

J'aimerais ne pas avoir à écrire ces 2 dernières lignes (addClass) ... mais bon, puisque nous n'avons pas de lien et que nous compilons en composant ... Je pense que je devrais m'en contenter pour l'instant.

9
Cokorda Raka

Tout d’abord, il existe une excellente documentation pour les composants Angularjs Compoents` . Je vous ai également déjà expliqué ce que vous faites et vous pouvez le rendre facultatif en l’utilisant ou en le vérifiant dans le contrôleur lui-même. 

Par exemple, vous gardez la liaison ici, mais dans votre contrôleur, vous avez quelque chose comme. 

var self = this;

// self.layout will be the value set by the binding.

self.$onInit = function() {
    // here you can do a check for your self.layout and set a value if there is none
    self.layout = self.layout || 'default value'; 
}

Cela devrait faire l'affaire. Si ce n'est pas le cas, il existe d'autres points d'ancrage du cycle de vie. Mais je l'ai fait avec mes composants et je l'ai même utilisé dans $ onChanges qui s'exécute avant $ onInit et vous pouvez réellement vérifier isFirstChange() dans la fonction $ onChanges, qui, j'en suis sûr, ne s'exécutera qu'une seule fois. Mais je n'ai pas testé cela moi-même. 

Vous pouvez y jeter un œil aux autres crochets du cycle de vie.

Modifier

C'est intéressant, puisque je l'ai déjà utilisé de cette façon. Vous pourriez être confronté à un autre problème. Bien que voici une idée. Que se passe-t-il si vous définissez la valeur enregistrée sur une variable dans le contrôleur parent et la transmettez au composant avec "<" au lieu de "@"? De cette façon, vous passez par référence au lieu de valeur et vous pouvez définir une surveillance sur quelque chose et modifier la variable si rien n'est défini pour cette variable, ce qui en fait une valeur par défaut. 

Avec angularjs, les composants '@' ne sont pas surveillés par le composant, mais avec '<', toute modification apportée au parent de ce composant est transmise au composant et est visible à cause de '<'. Si vous deviez changer '@' dans le contrôleur parent, votre composant ne verrait pas ce changement car il ne fait pas partie de l'objet onChanges, seules les valeurs '<' le sont. 

11
mjwrazor

Pour définir la valeur si la valeur liée n'est pas définie ask si la valeur est undefined ou null dans $onInit().

const ctrl = this;
ctrl.$onInit = $onInit;
function $onInit() {
  if (angular.isUndefined(ctrl.layout) || ctrl.layout=== null)
    ctrl.layout = 'column';
}

Cela fonctionne même si la valeur de layout serait false.

5
flob

Définir les vars de liaison dans le constructeur lancera simplement les vars avec les valeurs par défaut souhaitées. Après l'initialisation, les valeurs sont mises à jour avec la liaison.

    //ES6
    constructor(){
      this.layout = 'column';
    }
    $onInit() {
      // nothing here
    }
1
Anil Maharjan

vous pouvez utiliser

$onChanges({layout}) {
    if (! layout) { return; }
    this.setupLayout(); ---> or do whatever you want to do
}
0
Tamesh