[英]active tab issue in angular 2 - tabs
需要幫助修復 angular 2 應用程序中的活動選項卡問題。
我正在從 json 加載選項卡和相應的信息。
我有復雜的 json 格式,但在這里我制作了簡化版本。
問題:在初始階段未設置活動選項卡。
預期:第一個選項卡“選項卡 1”需要具有活動類。
請注意:單擊選項卡時,已添加活動類。 所以需要修復第一個元素的活動選項卡。 所以我們應該干擾其他功能。
任何幫助表示贊賞。
傑森
[
{
"id": "1",
"name": "Tabs 1",
"content": [
{
"header": "Basic Information",
"contents": [
{
"label": "Report 1"
}
]
}
]
},
{
"id": "2",
"name": "Tabs 2",
"content": [
{
"header": " Information",
"contents": [
{
"label": "Report 2"
}
]
}
]
},
{
"id": "3",
"name": "Tabs 3",
"content": [
{
"header": " report",
"contents": [
{
"label": "Report 3"
}
]
}
]
},
{
"id": "4",
"name": "Tabs 4",
"content": [
{
"header": " content Report",
"contents": [
{
"label": "Report 4"
}
]
}
]
}
]
應用服務.ts
import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';
@Injectable()
export class DashboardService {
private _url: string = "./app/report.json";
constructor(private _http: Http) {}
getRecords() {
return this._http.get(this._url)
.map((response: Response) => response.json())
}
_errorHandler(error: Response) {
console.error(error);
return Observable.throw(error || "Server Error");
}
}
app.component.ts
import {Component,ContentChildren,QueryList, OnInit,
Injectable, Inject} from '@angular/core';
import {TAB_COMPONENTS} from './tabset';
import {Tab} from './tab';
import { DashboardService } from './app-service';
@Component({
selector: 'my-app',
template: `
<h2>App Component</h2>
<tabset>
<tab *ngFor="let tab of records" [title]="tab.name">
<div *ngFor="let header of tab.content">
{{header.header}}
<div *ngFor="let label of header.contents">{{label.label}}</div>
</div>
</tab>
</tabset>
`
})
@Injectable()
export class AppComponent implements OnInit {
records = [];
errorMsg: string;
constructor(@Inject(DashboardService) private _dashboardService: DashboardService) {
//this.getRecords();
}
// getting json values from report.json
// To build the form
ngOnInit() {
this._dashboardService.getRecords()
.subscribe(
resGetRecords => {
debugger;
this.records = resGetRecords
},
resRecordsError => this.errorMsg = resRecordsError
);
}
}
標簽文件
import { Component, Input } from "@angular/core";
@Component({
selector: 'tab',
template: `
<ng-content *ngIf="active"></ng-content>
`
})
export class Tab {
@Input() title = '';
@Input() active = false;
@Input() disabled = false;
}
tabset.ts
import {
Component,
Input,
Output,
ContentChildren,
HostListener,
EventEmitter
} from '@angular/core';
import { Tab } from './tab';
@Component({
selector: 'tabset',
template: `
<section class="tab-set">
<ul
class="nav"
[class.nav-pills]="vertical"
[class.nav-tabs]="!vertical">
<li
*ngFor="let tab of tabs"
[class.active]="tab.active">
<a
(click)="tabClicked(tab)"
class="btn"
[class.disabled]="tab.disabled">
<span>{{tab.title}}</span>
</a>
</li>
</ul>
<div class="tab-content">
<ng-content></ng-content>
</div>
</section>
`
})
export class Tabset {
@Input() vertical;
@Output() onSelect = new EventEmitter();
@ContentChildren(Tab) tabs;
ngAfterContentInit() {
const tabs = this.tabs.toArray();
const actives = this.tabs.filter(t => {
return t.active
});
if (actives.length > 1) {
console.error(`Multiple active tabs set 'active'`);
} else if (!actives.length && tabs.length) {
tabs[0].active = true;
}
}
tabClicked(tab) {
const tabs = this.tabs.toArray();
tabs.forEach(tab => tab.active = false);
tab.active = true;
this.onSelect.emit(tab);
}
}
export const TAB_COMPONENTS = [
Tabset,
Tab
];
如果您不從 json 加載數據,它會起作用,我的意思是您需要先等待一個異步行為。
第一次,你用一個空數組records = [];
初始化選項卡records = [];
(在app.component.ts 中)
在 tabset 組件中,在你的ngAfterContentInit 中,你只檢查第一個 tabs 數據,這一次是一個空數組,並用第一個 tab 初始化 tabset,這一次是undefined 。 所以沒有選項卡被設置為活動的,這就是為什么沒有選擇的選項卡。
並且只有在訂閱 http 后加載 JSON 數據時,選項卡數據才會更新為正確的內容((來自 json 的 4 個項目)),並且沒有檢查和設置默認選定選項卡的操作。
因此,您的解決方案是在設置所選選項卡之前訂閱選項卡中的更改:
ngAfterContentInit() {
this.tabs.changes.subscribe((changes)=> {
const tabs = this.tabs.toArray();
const actives = this.tabs.filter(t => {
return t.active
});
if (actives.length > 1) {
console.error(`Multiple active tabs set 'active'`);
} else {
this.tabClicked(tabs[0]);
}
});
}
添加:
如果你有這樣的錯誤:
Expression has changed after it was checked. Previous value: 'false'. Current value: 'true'.
您需要在此處的角度文檔中添加setTimeout()
ngAfterViewInit() 生命周期鈎子是一個重要的問題。 直到 Angular 顯示父視圖后,計時器組件才可用。 所以它最初顯示 0 秒。 然后 Angular 調用 ngAfterViewInit 生命周期鈎子,此時更新父視圖的倒計時秒數顯示為時已晚。 Angular 的單向數據流規則防止在同一周期內更新父視圖。 該應用程序必須等待一圈才能顯示秒數。
使用 setTimeout() 等待一個刻度,然后修改 seconds() 方法,以便它從計時器組件中獲取未來的值。
所以現在:
tabClicked(tab) {
const tabs = this.tabs.toArray();
tabs.forEach(tab => tab.active = false);
setTimeout( () => tab.active = true);
this.onSelect.emit(tab);
}
工作plunker: https ://plnkr.co/edit/AZpieA3kow3xGT8UCIaj ? p = preview
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.