web-dev-qa-db-fra.com

Pourquoi la propriété `replace` est-elle déconseillée dans les directives AngularJS?

Selon les docs de l'API , l'attribut replace des directives est obsolète. Ainsi, à l'avenir, toutes les directives se comporteront avec la valeur par défaut actuelle de replace: false.

Cela supprime la possibilité pour les développeurs de remplacer un élément de directive d'élément, sans remplacement apparent pour cette fonctionnalité.

Voir this plunk pour un exemple du fonctionnement des directives d'élément avec et sans replace: true.

Pourquoi cet attribut utile est-il déconseillé sans remplacement?

108
sbleon

[~ # ~] met à jour [~ # ~]

Un des collaborateurs a dit qu'il ne serait pas supprimé, mais les bogues connus ne seront pas corrigés. https://github.com/angular/angular.js/commit/eec6394a342fb92fba5270eee11c83f1d895e9fb#commitcomment-8124407

[~ # ~] original [~ # ~]

Voici le commit de cette modification: https://github.com/angular/angular.js/commit/eec6394a342fb92fba5270eee11c83f1d895e9fb

L’indicateur replace permettant de définir des directives qui remplacent l’élément sur lequel elles se trouvent sera supprimé à la prochaine version majeure angular). Cette fonctionnalité présente une sémantique difficile (par exemple, comment les attributs sont fusionnés) Cela conduit également à plus de problèmes que ce qu’il résout.En outre, avec WebComponents, il est normal d’avoir des éléments personnalisés dans le DOM.

Il me semble que c'est une combinaison de complexité et d'avantage pour maintenir le support.

Et apparemment, une des raisons utilisées par dev était qu’ils préféraient l’injection de balises sémantiquement correctes, remplaçant ainsi la balise custom directive.


Lisez les commentaires plus bas sur ce lien et apparemment, beaucoup de gens veulent qu'il reste.

70
LessQuesar

Si vous craignez que replace: true sera supprimé dans la prochaine version, vous pouvez utiliser une fonction postCompile pour répliquer le comportement.

/// Replace element with it's first child
Utils.replaceWithChild = function(element) {
    var child = angular.element(element[0].firstChild);
    Utils.mergeAttributes(element, child);
    element.replaceWith(child);
}

/// Copy attributes from sourceElement to targetElement, merging their values if the attribute is already present
Utils.mergeAttributes = function(sourceElement, targetElement) {
    var arr = sourceElement[0].attributes;
    for(var i = 0; i < arr.length; i++) {
        var item = arr[i];
        if(!item.specified)
            continue;

        var key = item.name;
        var sourceVal = item.value;
        var targetVal = targetElement.attr(key);

        if(sourceVal === targetVal)
            continue;

        var newVal = targetVal === undefined
            ? sourceVal
            : sourceVal + ' ' + targetVal;

        targetElement.attr(key, newVal);
    }
}

angular.module('test')
.directive('unwrap', function() {
    return {
        restrict: 'AE',
        templateUrl: 'unwrap.part.html',
        compile: function() {
            return function postCompile(scope, element, attr) {
                Utils.replaceWithChild(element);
            };
        }
    }; 
});
20
Markos

De GitHub:

Caitp - Il est déconseillé car il existe des problèmes très stupides connus avec replace: true, dont certains ne peuvent pas être résolus de manière raisonnable. Si vous faites attention et évitez ces problèmes, augmentez votre puissance, mais pour le bénéfice des nouveaux utilisateurs, il est plus facile de leur dire "cela vous donnera mal à la tête, ne le faites pas".

- numéro AngularJS # 7636

replace:true est obsolète

De la documentation:

replace ([DEPRECATED!], sera supprimé dans la prochaine version majeure - c'est-à-dire v2.0)

spécifiez ce que le modèle doit remplacer. La valeur par défaut est false.

  • true - le modèle remplacera l'élément de la directive.
  • false - le modèle remplacera le contenu de l'élément de la directive.

- API de directive complète AngularJS

6
georgeawg

Je dirais que c'est une bonne chose qu'elle ait été supprimée car elle vous empêche d'exposer le fonctionnement interne d'une directive (composant) au monde extérieur. Examinez votre modèle en tant que DOM fantôme et comparez votre directive à des éléments HTML normaux, tels qu'un bouton. Vous ne voyez pas ajouter toutes sortes de classes et appliquer un style à ces éléments lorsque vous les survolez ou les cliquez. Tout est "caché" à l'intérieur. Parce que la prise en charge de shadow DOM est quelque peu limitée pour le moment, il s'agit d'une solution de contournement, mais cela vous permet déjà d'être à l'épreuve du temps.

4
Bas Slagter