2

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
  • 2
    you're working outisde of angular, please avoid the use of insertAdjacentHTML, innerHTML and the likes Commented Dec 31, 2020 at 14:58

1 Answer 1

2

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> 
Sign up to request clarification or add additional context in comments.

3 Comments

thanks, but I know what *ngif does in template, but in my case I want it to add from component. It is not only about ngIf, but ngfor and other angular feature does not work in this case.
ngFor and other directives do not work for the same reasons I've described - the resulting html at build/runtime are completely different than why you as a developer write. I don't know your exact use case, but I recommend doing some research on loading dynamic components. The link I provided in my answer is a great start. There's tons of nice tutorials online that show more ways to use it as well.
I'm using this dropdown component cuppalabs.github.io/angular2-multiselect-dropdown/#/templating , 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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.