简体   繁体   中英

Angular2 unable to set DOM element attribute is hidden with ngIf?

I have the following div and a button:

<div *ngIf="shownOrNot" custom-name="smth" data-x="3" data-y="4"><div>Test</div></div>
<button (click)="showAndSetX()">Show and Change</button>

Assuming shownOrNot = false initially, when I click the button, it triggers this function in component:

showAndSetX() {
this.shownOrNot = !this.shownOrNot;
$("[custom-name='smth']").attr('data-x', 5);
console.log($("[custom-name='smth']").attr('data-x'));
}

The problem is, when I first click on the button to hide the div, I see "3" logged, which is correct. When I click on it again however, I see "undefined". When I click on it again, then I see "3" logged.

How can I make it such that I can set the attribute after it is displayed? Or is there an alternative to this?

UPDATE: I also tried it with .data instead of .attr, same behavior. Its almost like I have to do:

this.shownOrNot = !this.shownOrNot; // insert function that waits for $("[custom-name='smth']") to actually render in DOM before continuing to do $("[custom-name='smth']").attr('data-x', 5);

The names of the functions are different

showAndSetX() and shownOrNot()

That is easy.

first you implement AfterViewInit interface then your component should be like below:

import {Component, AfterViewInit} from '@angular/core';

@Component({ /* ... */ })
export class PostComponent implements  AfterViewInit {


    // your jquery DOM saver
    dom;

    // ... default check it on true because jquery can get DOM on View initialize
    shownOrNot = true;

    constructor() { }


    // initialize your DOM
    ngAfterViewInit()
    {
        this.dom = $("[custom-name='smth']");
    }

    showAndSetX() {
        console.log(this.dom.attr('data-x'));
        this.shownOrNot = !this.shownOrNot;
        this.dom.attr('data-x', 5);
    }

}

UPDATE: a little bit of more information on your sample code.

in every click listen DOM request with $("[custom-name='smth']") but when angular *ngIf directive hidden the DOM you can't create a new DOM with jquery selector on that so Jquery return undefined because can't find requested DOM.

one another way is use angular 2 like below

<div *ngIf="shownOrNot" [attr.data-x]="xValue" [attr.data-y]="yValue"><div>Test</div></div>
<button (click)="showAndSetX()">Show and Change</button>

and your component class should be similar below

    dom;

    shownOrNot = true;

    xValue = 3;

    yValue = 4;

    constructor() { }

    ngAfterViewInit()
    {
        this.dom = $("[data-name='smth']");
    }

    showAndSetX() {
        console.log(this.dom.attr('data-x'));
        this.shownOrNot = !this.shownOrNot;

        this.xValue = this.xValue == 3 ? 10 : 3;

        setTimeout(() => { console.log(this.dom.attr('data-x')); });
    }

actually don't need (dom property) but for testing its necessary.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM