【问题标题】:How to automate button click after component load in Angular 2+如何在Angular 2+中加载组件后自动单击按钮
【发布时间】:2018-12-14 14:25:00
【问题描述】:

我目前正尝试在 Angular 中加载组件后启动搜索功能。目前该功能是通过按下按钮调用的,但我想自动执行此操作。

<button mat-raised-button class="mat-white-button green-button" (click)="onSearch()" style="width: 184px; top: -5px;">
                <i class="fa fa-search" style="margin-bottom: 2px;"></i>&nbsp; Find Shoppers
            </button>

我目前正在尝试使用生命周期挂钩 ngAfterContentInit() 调用 this.onSearch() 函数,但这不起作用。看起来函数调用是在组件加载时进行的,但从未完成。

     @Component({
    templateUrl: 'search.screen.html',
})

export class SearchScreen implements OnInit {

    _dealerId: number;
    public searching: boolean;
    public form: FormGroup;
    public noResultsFound: boolean;
    public viewChecked = false;

    startDate: Date;
    endDate: Date;
    minDate: Date;
    maxDate: Date;

    private searchSubscription: Subscription;

    // for the mat-header table component
    displayedColumns = ['name', 'email', 'phone', 'stage', 'currentVehicle', 'topVehicle', 'mappedDate'];
    shopperCount: number;

    dataSource: MatTableDataSource<SearchResult> = new MatTableDataSource<ActiveShopperSearchResult>();

    private paginator: MatPaginator;
    private sort: MatSort;

    @ViewChild(MatSort) set matSort(ms: MatSort) {
        this.sort = ms;
        this.setDataSourceAttributes();
    }

    @ViewChild(MatPaginator) set matPaginator(mp: MatPaginator) {
        this.paginator = mp;
        this.setDataSourceAttributes();
    }

    constructor(
        private everestApiService: EverestApiService,
        private _router: Router,
        private dialog: MatDialog,
        private _route: ActivatedRoute,
        private perms: PermissionsService,
    ) {
        this.form = new FormGroup({
            name: new FormControl(null),
            phone: new FormControl(null),
            email: new FormControl(null),
        });
    }

    ngOnInit() {
        this._dealerId = +this._route.snapshot.params['dealerId'];

        let startDateOffset = (24 * 60 * 60 * 1000) * 30; // 30 days offset
        let startDate = new Date();
        startDate.setTime(startDate.getTime() - startDateOffset);
        this.startDate = new Date(startDate.toString());
        this.endDate = new Date();

        let minDateOffset = (24 * 60 * 60 * 1000) * 365;
        let minDate = new Date();
        minDate.setTime(minDate.getTime() - minDateOffset);
        // this.onSearch();

    }
    ngAfterContentInit() {
        if(this.viewChecked === false) {
        this.onSearch();
        console.log(this.viewChecked)
        this.viewChecked = true;
        console.log(this.viewChecked)


        }
    }

 onSearch() {
        console.log('searching');
        this.clearResults();
        let searchParams = '?startDate=' + this.startDate.toISOString().substr(0, 10)
            + '&endDate=' + this.endDate.toISOString().substr(0, 10);

        if (this.form.value.name) {
            searchParams += '&name=' + this.form.value.name;
        }

        if (this.form.value.email) {
            searchParams += '&email=' + this.form.value.email;
        }

        if (this.form.value.phone) {
            searchParams += '&phone=' + this.form.value.phone;
        }

        this.searchSubscription = this.everestApiService.searchActiveShoppers(this._dealerId, searchParams)
            .pipe(track(inProgress => this.searching = inProgress))
            .subscribe((data) => {
                this.dataSource = new MatTableDataSource<ActiveShopperSearchResult>();
                this.dataSource.data = data;
                this.shopperCount = data.length;
                if (data.length === 0) {
                    this.noResultsFound = true;
                }
            });
    }

【问题讨论】:

  • 你怎么知道它从未完成?
  • 向我们展示 onSearch 功能
  • 添加了 onSearch() 函数。我知道它没有完成,因为我在“搜索”时有一个微调器,一旦搜索完成,它就会消失,并且屏幕会填充结果或显示未找到结果的消息。在当前状态下,我只能无限期地获得微调器。
  • ngAfterContentInit添加一些console.log语句,看看是否打印。在 if 和 outside 里面添加它,看看打印了什么。 (this.viewChecked === false) 很可能正在制造问题。

标签: javascript html angular typescript single-page-application


【解决方案1】:

将一些console.log 语句添加到ngAfterContentInit,看看它是否打印。 在 if 和 outside 里面添加它,看看打印了什么。 AfterViewInit() 和 AfterViewChecked() 钩子在创建组件的子视图后由 Angular 调用。

你的组件也应该实现implements AfterViewChecked:

 export class SearchScreen implements OnInit, AfterViewChecked  { 

       ngAfterContentInit() {
        if(this.viewChecked === false) {
        this.onSearch();
        console.log(this.viewChecked)
        this.viewChecked = true;
        console.log(this.viewChecked)
       }
     }

   }

【讨论】:

    【解决方案2】:

    如果你想在ngAfterContentInit() 中调用onSearch() 方法,你可以这样做。

    在.html中定义模板变量#buttonSearch

    .html

    <button #buttonSearch mat-raised-button class="mat-white-button green-button" (click)="onSearch()" style="width: 184px; top: -5px;">
    <i class="fa fa-search" style="margin-bottom: 2px;"></i>&nbsp; Find Shoppers
    </button>
    

    并调度该事件

    .ts

    @ViewChild('buttonSearch') private buttonSearch : ElementRef
    
    ngAfterContentInit() {
        if(this.viewChecked === false) {
        let event = new Event('click')
    
        this.buttonSearch.nativeElement.dispatchEvent(event)
    
        console.log(this.viewChecked)
        this.viewChecked = true;
        console.log(this.viewChecked)
        }
    }
    

    【讨论】:

    • 我得到一个'无法读取未定义的 nativeElement' w/这个解决方案。
    • 由于拼写错误,我在@ViewChild('buttonSearch ') 中添加了一个额外的空格。我已经编辑了答案。再试一次,然后告诉我。
    • 谢谢。但是我已经考虑了额外的空间并将其删除。我仍然遇到同样的错误。会不会是错误的生命周期钩子?
    • 这里是 jsfiddle jsfiddle.net/boilerplate/typescript 的链接。现在我收到“无法读取未定义的属性 dispatchEvent”。我从父 div 中取出 *ngIf。
    • 记得保存你的 jsfiddle,我只是看到一个打字稿样板。
    猜你喜欢
    • 2021-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-15
    • 2019-11-02
    • 1970-01-01
    • 1970-01-01
    • 2014-12-17
    相关资源
    最近更新 更多