te')); return $arr; } /* 遍历用户所有主题 * @param $uid 用户ID * @param int $page 页数 * @param int $pagesize 每页记录条数 * @param bool $desc 排序方式 TRUE降序 FALSE升序 * @param string $key 返回的数组用那一列的值作为 key * @param array $col 查询哪些列 */ function thread_tid_find_by_uid($uid, $page = 1, $pagesize = 1000, $desc = TRUE, $key = 'tid', $col = array()) { if (empty($uid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('uid' => $uid), array('tid' => $orderby), $page, $pagesize, $key, $col); return $arr; } // 遍历栏目下tid 支持数组 $fid = array(1,2,3) function thread_tid_find_by_fid($fid, $page = 1, $pagesize = 1000, $desc = TRUE) { if (empty($fid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('fid' => $fid), array('tid' => $orderby), $page, $pagesize, 'tid', array('tid', 'verify_date')); return $arr; } function thread_tid_delete($tid) { if (empty($tid)) return FALSE; $r = thread_tid__delete(array('tid' => $tid)); return $r; } function thread_tid_count() { $n = thread_tid__count(); return $n; } // 统计用户主题数 大数量下严谨使用非主键统计 function thread_uid_count($uid) { $n = thread_tid__count(array('uid' => $uid)); return $n; } // 统计栏目主题数 大数量下严谨使用非主键统计 function thread_fid_count($fid) { $n = thread_tid__count(array('fid' => $fid)); return $n; } ?>javascript - How to set a dynamic "id" HTML attribute of an angular component? - Stack Overflow
最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to set a dynamic "id" HTML attribute of an angular component? - Stack Overflow

programmeradmin3浏览0评论

My problem is related to placing the same ponent with different parameters on the same page. In this case it is a ponent containing a chart from a third party Javascript library (D3JS) which needs an HTML id attribute to locate and modify the ponent's HTML contents.

Now this id attribute should contain a unique string for each chart placed on the page, and if I directly set it as a string from the parent ponent it works just fine:

<my-chart id="gaugeChart0"></my-chart>

The reason it works is I guess, because the id attribute exists right at ponent creation time and whatever code is trying to access it can do that right away.

However this chart is in turn embedded into a bootstrap 4 card layout, like so:

<div class="row">
    <div class="col-6">
        <div class="card">
            <div class="card-body">
                <div class="row">
                    <div class="col-5">
                        <my-chart id="gaugeChart0"></my-chart>
                    </div>
                    <div class="col-7">
                        ... Some other widgets ...
                    </div>
                </div>
            </div>
        </div>
    </div>
    <div class="col-6">
        <div class="card">
            <div class="card-body">
                <div class="row">
                    <div class="col-5">
                        <my-chart id="gaugeChart1"></my-chart>
                    </div>
                    <div class="col-7">
                        ... Some other widgets ...
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

Now to make it more convenient (and to easily bind to click events to the whole block etc.) I would like to extract the whole part beginning with <div class="card"> into a new ponent.

Let's say I call this new ponent WidgetContainerComponent which contains the chart as well as the bootstrap card layout including the other widgets defined there.

The resulting code when using this wrapper ponent would be:

<div class="row">
    <div class="col-6">
        <widget-container chartId="gaugeChart0"></widget-container>
    </div>
    <div class="col-6">
        <widget-container chartId="gaugeChart1"></widget-container>
    </div>
</div>

In order for that to work the WidgetContainerComponent has an input field

@Input() chartId: string;

that can be set.

What I want to do then is to set the id attribute of the MyChartComponent to the string that has been set to chartId:

<div class="card">
    <div class="card-body">
        <div class="row">
            <div class="col-5">
                <my-chart [id]="chartId"></my-chart>
            </div>
            <div class="col-7">
                ... Some other widgets ...
            </div>
        </div>
    </div>
</div>

But this does not work, as angular adds a prefix to the id attribute which results in something like ng-reflect-id.

I also tried setting the attribute with [attr.id] as described here and here:

<div class="card">
    <div class="card-body">
        <div class="row">
            <div class="col-5">
                <my-chart [attr.id]="chartId"></my-chart>
            </div>
            <div class="col-7">
                ... Some other widgets ...
            </div>
        </div>
    </div>
</div>

This results in the MyChartComponent having a straight id attribute, but it seems to be only added at a later stage within the lifecycle of the ponent.

I also tried to initialize the chart within the MyChartComponent only in ngOnInit and ngAfterContentInit, but this does not work as well.

Any suggestions or ideas are very wele!

My problem is related to placing the same ponent with different parameters on the same page. In this case it is a ponent containing a chart from a third party Javascript library (D3JS) which needs an HTML id attribute to locate and modify the ponent's HTML contents.

Now this id attribute should contain a unique string for each chart placed on the page, and if I directly set it as a string from the parent ponent it works just fine:

<my-chart id="gaugeChart0"></my-chart>

The reason it works is I guess, because the id attribute exists right at ponent creation time and whatever code is trying to access it can do that right away.

However this chart is in turn embedded into a bootstrap 4 card layout, like so:

<div class="row">
    <div class="col-6">
        <div class="card">
            <div class="card-body">
                <div class="row">
                    <div class="col-5">
                        <my-chart id="gaugeChart0"></my-chart>
                    </div>
                    <div class="col-7">
                        ... Some other widgets ...
                    </div>
                </div>
            </div>
        </div>
    </div>
    <div class="col-6">
        <div class="card">
            <div class="card-body">
                <div class="row">
                    <div class="col-5">
                        <my-chart id="gaugeChart1"></my-chart>
                    </div>
                    <div class="col-7">
                        ... Some other widgets ...
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

Now to make it more convenient (and to easily bind to click events to the whole block etc.) I would like to extract the whole part beginning with <div class="card"> into a new ponent.

Let's say I call this new ponent WidgetContainerComponent which contains the chart as well as the bootstrap card layout including the other widgets defined there.

The resulting code when using this wrapper ponent would be:

<div class="row">
    <div class="col-6">
        <widget-container chartId="gaugeChart0"></widget-container>
    </div>
    <div class="col-6">
        <widget-container chartId="gaugeChart1"></widget-container>
    </div>
</div>

In order for that to work the WidgetContainerComponent has an input field

@Input() chartId: string;

that can be set.

What I want to do then is to set the id attribute of the MyChartComponent to the string that has been set to chartId:

<div class="card">
    <div class="card-body">
        <div class="row">
            <div class="col-5">
                <my-chart [id]="chartId"></my-chart>
            </div>
            <div class="col-7">
                ... Some other widgets ...
            </div>
        </div>
    </div>
</div>

But this does not work, as angular adds a prefix to the id attribute which results in something like ng-reflect-id.

I also tried setting the attribute with [attr.id] as described here and here:

<div class="card">
    <div class="card-body">
        <div class="row">
            <div class="col-5">
                <my-chart [attr.id]="chartId"></my-chart>
            </div>
            <div class="col-7">
                ... Some other widgets ...
            </div>
        </div>
    </div>
</div>

This results in the MyChartComponent having a straight id attribute, but it seems to be only added at a later stage within the lifecycle of the ponent.

I also tried to initialize the chart within the MyChartComponent only in ngOnInit and ngAfterContentInit, but this does not work as well.

Any suggestions or ideas are very wele!

Share Improve this question edited Oct 21, 2018 at 15:44 aegger asked Aug 20, 2018 at 19:21 aeggeraegger 4601 gold badge6 silver badges15 bronze badges 2
  • < div id="{{myvariable}}" > – Eliseo Commented Aug 20, 2018 at 19:32
  • Hi, you mean writing <my-chart id="{{chartId}}"></my-chart> instead of <my-chart [id]="chartId"></my-chart>? I already tried this before, also in this case the id attribute name gets prefixed with an ng-reflect- string which results in a ng-reflect-id attribute which is not recognized as an HTML id attribute. I think however that I already figured it out, I will post an answer later. – aegger Commented Aug 21, 2018 at 11:15
Add a ment  | 

1 Answer 1

Reset to default 12

So I found a solution to this problem. The problem was twofold:

  1. The first problem was related to the requirement of having a genuine id attribute in contrast to the attribute name prefixed with ng-reflect- by angular.

    What I didn't know is that from Angular 4, this prefix gets added to any attribute which is declared as an @Input variable for the ponent in development mode (for an in-depth explanation see this post).

    The solution to this problem was to write [attr.id]=chartId instead of [id]=chartId. The reason is that in this case I needed to set an HTML Attribute, however using the square brackets notation I created a Property Binding. In order to dynamically set an HTML Attribute via the property binding syntax you have to add the prefix attr. to the attribute's name.

    For a good overview regarding all valid binding syntaxes see the Angular Docs. Specifically to review how to do attribute binding see this section.

  2. The second problem was that I tried to access the id attribute of the ponent when it has not yet been created. This problem is related to the lifecycle hooks of Angular, where there are different stages. For a good overview of Angular's lifecycle hooks, see this page.

    Because I didn't know it myself in detail, I will elaborate it here shortly.

    Angular es with a fixed set of lifecycle hooks which are called each time a ponent is set up and are also called in a predefined order. The hooks are defined as follows:

    1. constructor
    2. ngOnChanges
    3. ngOnInit
    4. ngDoCheck
      1. ngAfterContentInit
      2. ngAfterContentChecked
      3. ngAfterViewInit
      4. ngAfterViewChecked
    5. ngOnDestroy

    _

    Important to note is that elements created or prepared in one step can only be accessed in any of the subsequent steps. In my case I put all the code for the initialization of the chart into the ngAfterContentInit hook, however the ponent is only fully loaded when ngAfterViewInit is called.

    Finally the solution was to put the pre-initialization code into the constructor and to place the chart initialization code into the ngAfterViewInit method. At this stage the id attribute had been created properly and could be accessed by the chart.

发布评论

评论列表(0)

  1. 暂无评论