5
votes

Dart: opérateur de propagation pour le constructeur

Dans mon application flutter , j'ai des widgets comme ci-dessous:

const borderBase = (
  color: Colors.red,
  width: 2,
  style: BorderStyle.solid,
)

Container(
  decoration: BoxDecoration(
    border: Border.all(
      ...borderBase,
    ),
  ),
  child: Text('Container 1'),
)

Container(
  decoration: BoxDecoration(
    border: Border(
      top: BorderSide(
        ...borderBase,
      ),
    ),
  ),
  child: Text('Container 2'),
)
Container(
  decoration: BoxDecoration(
    border: Border(
      top: BorderSide(
        color: Colors.red,
        width: 2,
        style: BorderStyle.solid,
      ),
    ),
  ),
  child: Text('Container 2'),
)

Les deux utilisent les mêmes propriétés strong> pour leurs frontières . Donc, je me demandais s'il y avait une façon de opérateur-épandeur d'insérer les mêmes propriétés pour les deux widgets? Peut-être aimer:

Container(
  decoration: BoxDecoration(
    border: Border.all(
      color: Colors.red,
      width: 2,
      style: BorderStyle.solid,
    ),
  ),
  child: Text('Container 1'),
)


0 commentaires

4 Réponses :


4
votes

Une telle chose n'existe pas.

Un opérateur de diffusion est en cours de développement, mais il ne concerne que les listes, pas les classes ( https://github.com/dart-lang/language/issues/47 )


2 commentaires

Je vois. Il n'y a donc aucun moyen de réutiliser dynamiquement les mêmes propriétés? Cela signifie que je dois les répéter à chaque fois?


Oui, vous y êtes obligé. Mais vous pouvez en discuter sur la question. Je pense que c'est aussi une fonctionnalité intéressante.



3
votes

Vous pouvez faire quelque chose comme ceci:

const BorderSide borderBase = BorderSide(
  color: Colors.red,
  width: 2,
  style: BorderStyle.solid,
);

Container(
  decoration: BoxDecoration(
    border: Border.all(
      color: borderBase.color,
      width: borderBase.width,
      style: borderBase.style,
    ),
  ),
  child: Text('Container 1'),
)

Container(
  decoration: BoxDecoration(
    border: Border(
      top: borderBase,
    ),
  ),
  child: Text('Container 2'),
)

Ce n'est pas le meilleur mais il reste encore une certaine réutilisation.


2 commentaires

Mais de cette façon, j'obtiens des erreurs dans la variable borderBase disant Nom non défini 'couleur' ​​, et d'autres erreurs linter .


Oh, je pense que vous vouliez dire que borderBase var devrait utiliser la BorderSide () classe , non? Parce que cela semble fonctionner.



2
votes

Voici un exemple factice du modèle d'opérateur de propagation de mon pauvre homme:

Je crée un constructeur de copie pour les classes souvent recréées avec de légères modifications. C'est un travail supplémentaire lors de la définition, mais cela est payant à de nombreux endroits lorsque vous utilisez ces classes. Le même modèle peut être utilisé sur les classes standard en sous-classant - juste pour se connecter à la question spécifique.

class Address {
    final String street;
    final String city;
    final String state;

    Address({this.street, this.city, this.state});

    Address.copy(Address copy, {
        String street,
        String city,
        String state,
    }) : this (
        street: street ?? copy.street,
        city: city ?? copy.city,
        state: state ?? copy.state,
    );
}

class User {
    final String firstName;
    final String lastName;
    final Address address;
    final String email;

    User({this.firstName, this.lastName, this.address, this.email});

    User.copy(User copy, {
        String firstName,
        String lastName,
        Address address,
        String email,
    }) : this (
        firstName: firstName ?? copy.firstName,
        lastName: lastName ?? copy.lastName,
        address: address ?? copy.address,
        email: email ?? copy.email,
    );
}

void workWithUsers(User user) {
    final userChangedEmail = User.copy(user, email: 'new@email.com');
    final userMovedToAnotherStreet = User.copy(user, address: Address.copy(user.address, street: 'Newstreet'));
}


0 commentaires

2
votes

Maintenant que la fléchette a à la fois l'opérateur de propagation et extensions de classe , vous pourriez abuser des deux pour ajouter le support ... spread aux méthodes static . Bien que je doute que ce soit une bonne idée , j'ai créé un dartpad fonctionnel ( gist ) pour démontrer. Le résultat final ressemble à quelque chose comme:

final Border spreadBorder = Border.fromSides([
  ...Border(
    left: BorderSide(color: Colors.pink),
    right: BorderSide(color: Colors.pinkAccent),
  ).sides,
  ...Border(
    top: BorderSide(color: Colors.blue),
    bottom: BorderSide(color: Colors.blueAccent),
  ).sides,
]).scale(5);

enum _Side { top, right, bottom, left }

extension SpreadBorder on Border {
  Iterable<MapEntry<_Side, BorderSide>> get sides {
    return () sync* {
      if (top != BorderSide.none) {
        yield MapEntry(_Side.top, top);
      }
      // ...other yields
    }();
  }

  static Border fromSides(Iterable<MapEntry<_Side, BorderSide>> parts) {
    BorderSide top, right, bottom, left;

    for (final borderPart in parts) {
      switch (borderPart.key) {
        case _Side.top:
          top = borderPart.value;
          break;
        // ... other cases
      }
    }
    return Border(
      top: top,
      right: right,
      bottom: bottom,
      left: left,
    );
  }
}


0 commentaires