Add controls to html from component in Angular

Viewed 98

I have this kind of issue, want to add some extra html stuff to html content, with conditional logic. But problem is that angular does not recognize angular syntax, which is added manually from component.

  public isExist: boolean = false;
  @ViewChild('appDropdown') appUnit: any;

  ngOnInit(): void {
    var el = this.appUnit._elementRef.nativeElement.querySelector('.list-area');;
    el.insertAdjacentHTML('beforeend','<div class="list-item-container add-container">'
                                      +   '<a class="btn btn-add" title="New">'
                                      +     '<span>+</span>'
                                      +   '</a>'
                                      +   '<label *ngIf="isExist" class="item-label add-label">Add</label>'
      + '</div>');


  }

This is a fragment of code. I mean that *ngIf is not recognize by angular.

enter image description here

How could I do this, that angular be able to recognize it's own syntax at such times?

For more clarity, I'm using this dropdown component, I want to add some extra features to it. I want to add footer with buttons, capable of saving and editing records on it. But unfortunately it does not supports this kind of customization and my try is on initialization access to dropdown body and add this html manually from component

1 Answers

This is not the correct way to dynamically add elements in an Angular application. The proper way to create new DOM elements is to inject the Render2 service into your component and use the helper methods. Another alternative is to use the Dynamic Component Loader, which would allow you to define a component, and insert it at will.

Specifically in your case, I don't see why you even need Render2 or dynamic component loader.

@Component({
  selector: "my-component",
  template: `
    <div class="list-item-container add-container">
    <a class="btn btn-add" title="New">
      <span>+</span>
    </a>'
    <label *ngIf="isExist" class="item-label add-label">Add</label>
`
  styleUrls: ["./my-component.component.css"]
})
export class MyComponent {
  isExist = false;
}

The reason your method does not work is because the template syntax gets transformed into something completely different at build/run time. In fact, the *ngIf directive completely removes the element from the DOM if the condition isn't met.

To demonstrate, we can look at a very simple component on StackBlitz that uses *ngIf.

@Component({
  selector: "my-app",
  template: `
    <input type="checkbox" [(ngModel)]="isShown">
    <p *ngIf="isShown">
        I am some text!!
    </p>
  `
  styleUrls: ["./app.component.css"]
})
export class AppComponent {
  isShown = false;
}

The resulting HTML looks like this when it's initially rendered. Note that the <p> element is not in the DOM. You'll notice that the element doesn't actually have the *ngIf on it.

<my-app _nghost-dvn-c21="" ng-version="11.0.5">
   <input _ngcontent-dvn-c21="" type="checkbox" ng-reflect-model="false" class="ng-untouched ng-pristine ng-valid">
<!--bindings={ "ng-reflect-ng-if": "false" }-->
</my-app>

Then, if you check the box, the <p> element is now in the DOM.

<my-app _nghost-lsw-c0="" ng-version="11.0.5">
   <input _ngcontent-lsw-c0="" type="checkbox" ng-reflect-model="true" class="ng-valid ng-dirty ng-touched">
     <!--bindings={
      "ng-reflect-ng-if": "true"
      }-->
   <p _ngcontent-lsw-c0=""> I am some text!!</p>
</my-app> 
Related