当*ngIf条件在angular2中失败时,如何调用某些方法?

当*ngIf条件在angular2中失败时,如何调用某些方法?,angular,Angular,我有列表(ul)并在5个列表元素(li)上添加了ngIf条件。当条件满足时会显示它们。我想在ngIf条件满足或失败时调用一些方法。我在list元素上添加了指令,并在ngAfterViewInit()中调用了我的方法。但当条件失败时,它不会被调用。请提出解决办法。这是我的一段代码 <ul class="choose-list"> <li filter-selection (onWidthChange)="setfullWidth=$event" *ngIf="filter.co

我有列表(ul)并在5个列表元素(li)上添加了ngIf条件。当条件满足时会显示它们。我想在ngIf条件满足或失败时调用一些方法。我在list元素上添加了指令,并在ngAfterViewInit()中调用了我的方法。但当条件失败时,它不会被调用。请提出解决办法。这是我的一段代码

<ul class="choose-list">
<li filter-selection  (onWidthChange)="setfullWidth=$event" *ngIf="filter.country.name!=''"><span>{{filter.country.name}}</span><a (click)="onClearFilter('country')" href="#" class="mdi mdi-close"></a></li>
<li filter-selection  (onWidthChange)="setfullWidth=$event" *ngIf="filter.level.name!=''"><span>{{filter.level.name}}</span><a  (click)="onClearFilter('level')" href="#" class="mdi mdi-close"></a></li>
<li filter-selection (onWidthChange)="setfullWidth=$event" *ngIf="filter.institution.name!=''"><span>{{filter.institution.name}}</span><a (click)="onClearFilter('institution')" href="#" class="mdi mdi-close"></a></li>
<li filter-selection (onWidthChange)="setfullWidth=$event" *ngIf="filter.program.name!=''"><span>{{filter.program.name}}</span><a (click)="onClearFilter('program')" href="#" class="mdi mdi-close"></a></li>
<li filter-selection (onWidthChange)="setfullWidth=$event" *ngIf="filter.fromYear.name!=''"><span>{{filter.fromYear.name}}</span><a (click)="onClearFilter('fromYear')" href="#" class="mdi mdi-close"></a></li>
<li filter-selection (onWidthChange)="setfullWidth=$event" *ngIf="filter.toYear.name!=''"><span>{{filter.toYear.name}}</span><a (click)="onClearFilter('toYear')" href="#" class="mdi mdi-close"></a></li>
  </ul>

import { Directive, HostListener, ElementRef, AfterViewInit, Input, Output , EventEmitter, Renderer } from '@angular/core';


@Directive({selector: '[filter-selection]'})
export class FilterSelectionDirective implements AfterViewInit  {

filteredElement; 
addBox; 
list; 
stretchBox;
holder;  


@Output() onWidthChange: EventEmitter<boolean> = new EventEmitter<boolean>();

constructor(private elementRef: ElementRef, private renderer: Renderer) {
    this.filteredElement = elementRef.nativeElement;

}


ngAfterViewInit() {
    let ctrl = this;
    this.addBox = this.filteredElement.parentElement.previousElementSibling;
    this.list = this.filteredElement.parentNode;
    this.holder = this.filteredElement.parentNode.parentNode.parentNode.parentNode;
    this.stretchBox = this.holder.firstElementChild;

    setTimeout(function () {
        ctrl.refreshWidth()
    }, 0);
}



refreshWidth() {
    debugger;
    var listWidth = 0;

    var items = this.filteredElement.parentElement.children; // all li

    for (var i = 0; i < items.length; i++) {
        listWidth += $(items[i]).outerWidth(true);
    }
    console.log(listWidth);

    var newWidth;


    if (!items.length || $(this.addBox).outerWidth(true) + (listWidth + ($(this.list).outerWidth(true) - $(this.list).width())) > $(this.holder).width() * 0.7) {
        newWidth = '';
        this.renderer.setElementStyle(this.stretchBox, 'width', newWidth);
        this.onWidthChange.emit(true);  //add full width
    }
    else {
        this.onWidthChange.emit(false);  //remove full width
        newWidth = Math.floor((100 - (($(this.addBox).outerWidth(true) + (listWidth +
            ($(this.list).outerWidth(true)
                - $(this.list).width()))) / $(this.holder).width() * 100)) /** 10*/) /*/ 10*/ + '%';

        this.renderer.setElementStyle(this.stretchBox, 'width', newWidth);
    }
}
    {{filter.country.name} {{filter.level.name} {{{filter.institution.name} {{filter.program.name} {{filter.fromYear.name} {{filter.toYear.name}
从“@angular/core”导入{指令、HostListener、ElementRef、AfterViewInit、输入、输出、EventEmitter、渲染器}; @指令({选择器:'[filter selection]'}) 导出类筛选器选择指令在ViewInit之后实现{ 过滤去除; 地址盒; 列表 担架箱; 持有人 @Output()onWidthChange:EventEmitter=neweventemitter(); 构造函数(private-elementRef:elementRef,private-renderer:renderer){ this.filteredElement=elementRef.nativeElement; } ngAfterViewInit(){ 让ctrl=this; this.addBox=this.filteredElement.parentElement.previouselement同级; this.list=this.filteredElement.parentNode; this.holder=this.filteredElement.parentNode.parentNode.parentNode.parentNode.parentNode; this.stretchBox=this.holder.firstElementChild; setTimeout(函数(){ ctrl.refreshWidth() }, 0); } 刷新宽度(){ 调试器; var-listWidth=0; var items=this.filteredElement.parentElement.children;//所有li 对于(变量i=0;i$(this.holder.width()*0.7){ 新宽度=“”; this.renderer.setElementStyle(this.stretchBox'width',newWidth); this.onWidthChange.emit(true);//添加全宽 } 否则{ this.onWidthChange.emit(false);//删除全宽 newWidth=Math.floor((100-($(this.addBox)).outerWidth(true)+(listWidth+ ($(this.list).outerWidth(true) -$(this.list.width())/$(this.holder.width()*100))/**10*/)/*/10*/+'%'; this.renderer.setElementStyle(this.stretchBox'width',newWidth); } }
您可以注入

constructor(private cdRef:ChangeDetectorRef){}
打电话

this.cdRef.detectChanges();
删除项目后,要立即更新DOM,可以注入

constructor(private cdRef:ChangeDetectorRef){}
打电话

this.cdRef.detectChanges();

删除项目后,立即更新DOM是个坏主意。

每次运行更改检测时,角度更改检测都会调用这些方法,这比条件在真/假之间变化的频率要高。更改模型以发出事件(例如,当属性更改时使用
可观察的
,然后从那里调用您的方法。谢谢!问题是当我在clearFilters()中调用refrehwidth()时,列表项尚未从DOM树中删除。ngIf渲染在clearFlter()之后完成).var items=this.filteredElement.parentElement.children;您可以插入
构造函数(私有cdRef:ChangeDetectorRef){}
并调用
this.cdRef.detectChanges()
删除项目后,立即更新DOM-不过我看不到
*ngFor
。你的代码没有多大意义。你应该尝试使用更多绑定,而不是
渲染器…
。谢谢!这对我来说很有效。这是个坏主意。每次运行更改检测时,角度更改检测都会调用这些方法,这比条件在true/false之间更改的频率要高。更改模型以在属性更改时发出事件(例如,使用
可观察的
,然后从那里调用方法。谢谢!问题在于我在clearFilters()中调用refrehwidth()时,列表项尚未从DOM树中删除。ngIf呈现在clearFlter()之后完成。var items=this.filteredElement.parentElement.children;您可以插入
构造函数(私有cdRef:ChangeDetectorRef){}
并调用
this.cdRef.detectChanges()
删除项目以立即更新DOM后-虽然我没有看到
*ngFor
。您的代码没有多大意义。您应该尝试使用更多绑定,而不是
渲染器…
。谢谢!这对我很有效。当我将子组件添加到此组件时,它会出现异常TypeError:无法读取未定义的属性“ngDoCheck”。抱歉,这还不够。您是否在某处自己调用了
ngDoCheck
?否,当我注释此.cdRef.detectChanges()时,则不会发生异常当我将子组件添加到此组件时,它会给出异常TypeError:无法读取未定义的属性“ngDoCheck”。抱歉,这还不够。您是否正在自己的某个地方调用
ngDoCheck
?否,当我注释此.cdRef.detectChanges()时,则不会发生异常