使用 *ngIf 指令的 ng-container 意外行为
ng-container unexpected behavior with *ngIf directive
我的项目中有一个 ng-container,它应该 show/hide 我的 HTML 的一部分,具体取决于某个 属性。
当 属性 最初为 false,之后我将其设置为 true - ng-container 中的内容按预期显示。但是,当 属性 最初为真时 - 内容不会显示。
HTML代码:
<ion-item>
<ng-container *ngIf="prop">
<ion-item>
<ion-label stacked [innerHTML]="htmlString"></ion-label>
<ion-checkbox (click)="checkboxClick($event)"></ion-checkbox>
</ion-item>
</ng-container>
</ion-item>
这里有一个 EXAMPLE 的初始 属性 是假的。
改成true后显示内容
这里有一个 EXAMPLE 的初始 属性 为真。
什么也没有显示。
如果该值最初为真,如何显示内容?
好的,问题是您需要定义 ng-container 包含 ion-item 的内容。
Documented on the ionic framework site.
<ion-item>
<ng-container *ngIf="prop" item-content> <!-- this right here -->
<ion-item>
<ion-label stacked [innerHTML]="htmlString"></ion-label>
<ion-checkbox (click)="checkboxClick($event)"></ion-checkbox>
</ion-item>
</ng-container>
</ion-item>
问题在于 ion-item
如何呈现其模板。因为您的容器内有一个 ion-label
,所以 parent ion-item
假定您的项目内容在模板中找到的这个 ion-label
内;因此忽略所有其余部分。
所以问题不是真正的 ng-container
而是 ion-item
它本身,当它以 prop=false
开始时,它不会呈现直到 angular 检测到更改并构建代码的这个特定部分;因此 ion-item
得到正确构建。但是当它开始时 true
ion-item
自己把它扔掉了。
整个ion-item
模板:
template:
'<ng-content select="[item-start],[item-left],ion-checkbox:not([item-end]):not([item-right])"></ng-content>' +
'<div class="item-inner">' +
'<div class="input-wrapper">' +
'<ng-content select="ion-label"></ng-content>' +
'<ion-label *ngIf="_viewLabel">' +
'<ng-content></ng-content>' +
'</ion-label>' +
'<ng-content select="ion-select,ion-input,ion-textarea,ion-datetime,ion-range,[item-content]"></ng-content>' +
'</div>' +
'<ng-content select="[item-end],[item-right],ion-radio,ion-toggle"></ng-content>' +
'<ion-reorder *ngIf="_hasReorder"></ion-reorder>' +
'</div>' +
'<div class="button-effect"></div>'
如下所示,它查找 ion-label
(第一行 select="ion-label"
),如果找到,则将其用作项目的内容,否则创建一个新的 ion-label
,其中包含您的 ion-item
的内容 (ng-content
)。
ion-item
模板的相关部分:
'<ng-content select="ion-label"></ng-content>' +
'<ion-label *ngIf="_viewLabel">' +
'<ng-content></ng-content>' +
'</ion-label>' +
'<ng-content select="ion-select,ion-input,ion-textarea,ion-datetime,ion-range,[item-content]"></ng-content>' +
最终,这只是组件之间的冲突,因为您在另一个组件中使用一个 ion-item
。
解决这个问题的方法是使用<ng-container *ngIf="prop" item-content>
(正如@Jacques 的建议),它将使插槽被之前描述的第三个插槽捕获,该插槽选择 [item-content]
作为目标而不是尽管 child ion-item
.
上有 ion-label
,但仍丢失了内容
'<ng-content select="ion-select,ion-input,ion-textarea,ion-datetime,ion-range,[item-content]"></ng-content>' +
Disclaimer: I only give my answer because the previous answer doesn't explain why this happen, consider this a complement.
我的项目中有一个 ng-container,它应该 show/hide 我的 HTML 的一部分,具体取决于某个 属性。
当 属性 最初为 false,之后我将其设置为 true - ng-container 中的内容按预期显示。但是,当 属性 最初为真时 - 内容不会显示。
HTML代码:
<ion-item>
<ng-container *ngIf="prop">
<ion-item>
<ion-label stacked [innerHTML]="htmlString"></ion-label>
<ion-checkbox (click)="checkboxClick($event)"></ion-checkbox>
</ion-item>
</ng-container>
</ion-item>
这里有一个 EXAMPLE 的初始 属性 是假的。 改成true后显示内容
这里有一个 EXAMPLE 的初始 属性 为真。 什么也没有显示。
如果该值最初为真,如何显示内容?
好的,问题是您需要定义 ng-container 包含 ion-item 的内容。
Documented on the ionic framework site.
<ion-item>
<ng-container *ngIf="prop" item-content> <!-- this right here -->
<ion-item>
<ion-label stacked [innerHTML]="htmlString"></ion-label>
<ion-checkbox (click)="checkboxClick($event)"></ion-checkbox>
</ion-item>
</ng-container>
</ion-item>
问题在于 ion-item
如何呈现其模板。因为您的容器内有一个 ion-label
,所以 parent ion-item
假定您的项目内容在模板中找到的这个 ion-label
内;因此忽略所有其余部分。
所以问题不是真正的 ng-container
而是 ion-item
它本身,当它以 prop=false
开始时,它不会呈现直到 angular 检测到更改并构建代码的这个特定部分;因此 ion-item
得到正确构建。但是当它开始时 true
ion-item
自己把它扔掉了。
整个ion-item
模板:
template:
'<ng-content select="[item-start],[item-left],ion-checkbox:not([item-end]):not([item-right])"></ng-content>' +
'<div class="item-inner">' +
'<div class="input-wrapper">' +
'<ng-content select="ion-label"></ng-content>' +
'<ion-label *ngIf="_viewLabel">' +
'<ng-content></ng-content>' +
'</ion-label>' +
'<ng-content select="ion-select,ion-input,ion-textarea,ion-datetime,ion-range,[item-content]"></ng-content>' +
'</div>' +
'<ng-content select="[item-end],[item-right],ion-radio,ion-toggle"></ng-content>' +
'<ion-reorder *ngIf="_hasReorder"></ion-reorder>' +
'</div>' +
'<div class="button-effect"></div>'
如下所示,它查找 ion-label
(第一行 select="ion-label"
),如果找到,则将其用作项目的内容,否则创建一个新的 ion-label
,其中包含您的 ion-item
的内容 (ng-content
)。
ion-item
模板的相关部分:
'<ng-content select="ion-label"></ng-content>' +
'<ion-label *ngIf="_viewLabel">' +
'<ng-content></ng-content>' +
'</ion-label>' +
'<ng-content select="ion-select,ion-input,ion-textarea,ion-datetime,ion-range,[item-content]"></ng-content>' +
最终,这只是组件之间的冲突,因为您在另一个组件中使用一个 ion-item
。
解决这个问题的方法是使用<ng-container *ngIf="prop" item-content>
(正如@Jacques 的建议),它将使插槽被之前描述的第三个插槽捕获,该插槽选择 [item-content]
作为目标而不是尽管 child ion-item
.
ion-label
,但仍丢失了内容
'<ng-content select="ion-select,ion-input,ion-textarea,ion-datetime,ion-range,[item-content]"></ng-content>' +
Disclaimer: I only give my answer because the previous answer doesn't explain why this happen, consider this a complement.