web-dev-qa-db-ja.com

AngularJSディレクティブで `replace`プロパティが非推奨になったのはなぜですか?

API docs によると、ディレクティブのreplace属性は廃止されるため、将来、すべてのディレクティブは現在のデフォルトのreplace: falseで動作します。

これにより、開発者が要素ディレクティブの要素を置き換える機能が削除され、この機能の明らかな置き換えはありません。

エレメントディレクティブがreplace: trueを使用する場合と使用しない場合の例については、 this plunk を参照してください。

なぜこの便利な属性は置き換えられずに廃止されるのですか?

108
sbleon

UPDATE

共同編集者の1人は、削除しないと言っていますが、既知のバグは修正されません。 https://github.com/angular/angular.js/commit/eec6394a342fb92fba5270eee11c83f1d895e9fb#commitcomment-8124407

オリジナル

この変更のコミットは次のとおりです。 https://github.com/angular/angular.js/commit/eec6394a342fb92fba5270eee11c83f1d895e9fb

存在する要素を置き換えるディレクティブを定義するためのreplaceフラグは、次のメジャーangularバージョンで削除されます。この機能にはセマンティクスが難しく(属性のマージ方法など)、解決するものと比較してより多くの問題が発生します。また、WebComponentsでは、DOMにカスタム要素があるのが普通です。

サポートを維持するための複雑さと利益の組み合わせのように思えます。

また、開発者がセマンティックに正しいマークアップを挿入することを好み、カスタムディレクティブタグを置き換えるため、devがそれを使用していたようです。


そのリンクの下のコメントを読んでください。どうやら多くの人がそれを維持したいと思っているようです。

70
LessQuesar

replace: trueが次のバージョンで削除されることを恐れている場合は、postCompile関数を使用して動作を再現できます。

/// 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

GitHubから:

Caitp-replace: trueには既知の非常に馬鹿げた問題があり、その多くは実際には合理的な方法で修正できないため、非推奨です。注意してこれらの問題を回避すれば、より強力になりますが、新規ユーザーの利益のために、「これは頭痛の種になります。やるな」と言う方が簡単です。

- AngularJS Issue#7636

replace:trueは非推奨です

ドキュメントから:

replace([非推奨!]、次のメジャーリリースで削除されます-すなわちv2.0)

テンプレートが置き換えるものを指定します。デフォルトはfalseです。

  • true-テンプレートはディレクティブの要素を置き換えます。
  • false-テンプレートはディレクティブの要素の内容を置き換えます。

- AngularJS包括的なディレクティブAPI

6
georgeawg

ディレクティブ(コンポーネント)の内部動作を外部に公開することができないため、削除されたのは良いことだと思います。テンプレートをシャドウDOMとして見て、ディレクティブをボタンのような通常のHTML要素と比較します。ホバーまたはクリックしたときに、すべての種類のクラスが追加され、それらの要素にスタイルが適用されません。それはすべて「隠された」内部です。現時点では、シャドウDOMのサポートは多少制限されているため、回避策のようなものですが、すでに将来の証拠になることができます。

4
Bas Slagter