Why is `replace` property deprecated in AngularJS directives? [duplicate]

Asked
Active3 hr before
Viewed126 times

8 Answers

replaceproperty
90%

According to the API docs, directives' replace attribute is deprecated, so in the future, all directives will behave with the current default of replace: false.,This removes developers' ability to replace an element directive's element, with no apparent replacement for this functionality.,And apparently one reason dev were using it because they prefered semantically correct markup to be injected , thus replacing the custom directive tag., 1 its not a good solution because replace deprecated for concept not feature , we usually don't have any css for the directive element then we dont see any effect of the primary element – Ali.MD May 11 '15 at 6:20

If you fear that replace: true will be removed in next version, you can use a postCompile function to replicate the behavior.

/// 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);
            };
         }
      };
   });
88%

Why is this useful attribute being deprecated with no replacement?,See this plunk for an example of how element directives work with and without replace: true.,According to the API docs, directives' replace attribute is deprecated, so in the future, all directives will behave with the current default of replace: false.,This removes developers' ability to replace an element directive's element, with no apparent replacement for this functionality.

What you'll need to do is to transclude the contents of the directive. The usual use for this is that you want the contents to be in the parent scope of the directive, and not in the isolated scope. However, you want the content to be in the isolated scope of the directive. So you'll have to call the transclude function manually, and bind the contents to the isolated scope of the directive:

.directive("draggable", function($compile) {
   return {
      transclude: true,
      scope: {
         target: "="
      },
      link: function(scope, element, attrs, ctrl, transclude) {
         transclude(scope, function(clone) {
            element.append(clone);
         });
      }
   }
})
load more v
72%

Specifies what the template should replace. Defaults to false.,true - the template will replace the directive's element.,Template loading is asynchronous even if the template has been preloaded into the $templateCache.,See also the directive.templateNamespace property.

angular.module('do-check-module', [])
.component('app', {
  template:
    'Month: <input ng-model="$ctrl.month" ng-change="$ctrl.updateDate()">' +
    'Date: {{ $ctrl.date }}' +
    '<test date="$ctrl.date"></test>',
  controller: function() {
    this.date = new Date();
    this.month = this.date.getMonth();
    this.updateDate = function() {
      this.date.setMonth(this.month);
    };
  }
})
.component('test', {
  bindings: { date: '<' },
  template:
    '<pre>{{ $ctrl.log | json }}</pre>',
  controller: function() {
    var previousValue;
    this.log = [];
    this.$doCheck = function() {
      var currentValue = this.date && this.date.valueOf();
      if (previousValue !== currentValue) {
        this.log.push('doCheck: date mutated: ' + this.date);
        previousValue = currentValue;
      }
    };
  }
});
load more v
65%

When I create a directive with a template that has a class attribute and replace: true. The attrs parameter in the link function duplicates the classes. They are also duplicated when I look at the element in the HTML.,This appears to only happen when the tag that the directive is replacing also has a class attribute.,replace: true will merge attribute values from the compiled node into the root of the replaced node.,@caitp, @jstrength is referring to the fact that the "center-block" class is repeated twice on the class attribute, where it should only be there once.

<test class="btn-block"></test>
load more v
75%

replace: true. Angular never replaces a component element with the component template. This attribute is also deprecated in AngularJS.,Convert the phone detail component template into Angular syntax as follows:,require, if the component needs to communicate with some parent component's controller.,Angular components that support content projection make use of an <ng-content> tag within them. Here's an example of such a component:

export function heroDetailDirective() {  return {    restrict: 'E',    scope: {},    bindToController: {      hero: '=',      deleted: '&'    },    template: `      <h2>{{ctrl.hero.name}} details!</h2>      <div><label>id: </label>{{ctrl.hero.id}}</div>      <button ng-click="ctrl.onDelete()">Delete</button>    `,    controller: function() {      this.onDelete = () => {        this.deleted({hero: this.hero});      };    },    controllerAs: 'ctrl'  };}
load more v
40%

The AngularJS framework is on Long Term Support ("LTS") until December 31, 2021.[3][4] After that date Google will no longer update AngularJS to fix security, browser compatibility, or jQuery issues.[5][4] The Angular team recommends upgrading to Angular (v2+) as the best path forward, but they also provided some other options.[6] ,5.2 Angular and AngularDart,A normal Angular application executes in the browser, while Angular Universal generates static application pages on the server through server-side rendering (SSR).[27] ,AngularJS directives allow the developer to specify custom and reusable HTML-like elements and attributes that define data bindings and the behavior of presentation components. Some of the most commonly used directives are:

load more v
22%

Triggering change detection manually in Angular,Can’t bind to ‘ngModel’ since it isn’t a known property of ‘input’,Can’t bind to ‘formGroup’ since it isn’t a known property of ‘form’,Angular CLI SASS options

The Constructor is a default method of the class that is executed when the class is instantiated and ensures proper initialization of fields in the class and its subclasses. Angular or better Dependency Injector (DI) analyzes the constructor parameters and when it creates a new instance by calling new MyClass() it tries to find providers that match the types of the constructor parameters, resolves them and passes them to the constructor like

new MyClass(someArg);
load more v
60%

Angular transforms the *ngFor in similar fashion from asterisk (*) syntax through template attribute to template element.,The Angular microsyntax lets you configure a directive in a compact, friendly string. The microsyntax parser translates that string into attributes on the <template>:,that the Angular desugars asterisk (*) syntax into a <template>.,The asterisk is syntactic sugar for something a bit more complicated. Internally, Angular desugars it into a template element, wrapped around the host element, like this.

<div *ngIf="hero != null" >{{hero.name}}</div>
load more v

Other "replace-property" queries related to "Why is `replace` property deprecated in AngularJS directives? [duplicate]"