我想基于布尔属性在两个列表之间切换项目。我无法理解如何让列表组件重新渲染并显示更新的列表。
当"改变转变"按下按钮," nocturnal"属性切换和类更改。缺少的行为是我还希望项目(即蝙蝠侠)从夜间列表移动到日期列表
我的应用程序组件包括主(列表)和详细信息组件。模板代码:
<div>
<my-list [list]="listSource"></my-list>
<my-detail [selected]="selectedItem"></my-detail>
</div>
列出组件模板:
<div class="column list">
<h2>List</h2>
<h3>Day Shift</h3>
<ul>
<li *ngFor="let item of listDay" class="{{ item.nocturnal ? 'night':'day'}}">{{ item.name }}</li>
</ul>
<h3>Night Shift</h3>
<ul>
<li *ngFor="let item of listNight" class="{{ item.nocturnal ? 'night':'day'}}">{{ item.name }}</li>
</ul>
</div>
主列表在List组件中被过滤为listDay
和listNight
,如下所示:
ngOnInit() {
this.listNight = this.list.filter(item => item.nocturnal);
this.listDay = this.list.filter(item => !item.nocturnal);
}
详情组件模板:
<div class="column detail">
<h2>Detail</h2>
<ul>
<li>name: {{selected.name}}</li>
<li>job: {{selected.job}}</li>
<li>shift: {{selected.nocturnal ? 'Night':'Day'}}</li>
<li><button (click)="toggleShift()">Change Shift</button></li>
</ul>
</div>
这是一个基本的Plunkr,说明了这个问题: http://plnkr.co/edit/yJLtROrmfKjEYqj5yJ1N?p=preview
答案 0 :(得分:1)
好吧,你的捡拾器有点乱,所以我从头开始。而不是两个子组件给一个父母,我只做了一个孩子到一个父母。但是这种方法你仍然可以通过一些改变来实现。
您可以使用ngOnChanges,observables或可变数据解决此问题(此解决方案使用可变数据)。在将来,我建议从服务器获取此数据,并使用行为主题来跟踪更新,因为它会使您的应用程序陷入低于ngOnChanges,并且可观察性是一种很好的做法。
你的方法不起作用的原因是Angular的变化检测不起作用,因为列表发生了变异。这就是我如何解决它,每次进行更改时,我都使用spread(...
)运算符来复制原始列表的内容并创建一个新列表。你走了。
这是答案的stackBlitz,您可以使用它来构建您的版本。
如果您想了解有关智能/哑主/详细模式的更多信息,可以查看here
答案 1 :(得分:1)
不确定FussinHussin现有的答案是否能为您提供您所描述的问题。我成功转移了蝙蝠侠&#34;按下切换按钮时,从日夜列表中来回切换。以下是我修改过的更新的plunker文件。
app.ts
// root app component
import {Component, NgModule, VERSION} from '@angular/core'
import {BrowserModule} from '@angular/platform-browser'
import {List} from './list.component'
import {Detail} from './detail.component'
@Component({
selector: 'my-app',
template: `
<div>
<h2>Hello {{name}}</h2>
<my-list [list]="listSource"></my-list>
<my-detail [selected]="selectedItem" (shiftChange)="shiftChanged($event)"></my-detail>
</div>
`,
})
export class App {
name:string;
listSource:any
selectedItem:any;
constructor() {
this.name = `Angular! v${VERSION.full}`;
this.listSource = [{
'name':'Batman',
'job':'Detective',
'nocturnal':true
},{
'name':'Superman',
'job':'Carpenter',
'nocturnal':false
},{
'name':'Aquaman',
'job':'Plumber',
'nocturnal':false
},{
'name':'Herman',
'job':'Physicist',
'nocturnal':true
}];
this.selectedItem = this.listSource[0];
}
shiftChanged(listItem: any) {
let index = null;
for (let i=0; i<this.listSource.length; i++) {
if (listItem.name === this.listSource[i].name) {
index = i;
break;
}
}
if (index !== null) {
this.listSource[index].nocturnal = listItem.nocturnal;
this.listSource = JSON.parse(JSON.stringify(this.listSource));
}
}
}
// root module
@NgModule({
imports: [ BrowserModule ],
declarations: [ App, List, Detail ],
providers:[ ],
bootstrap: [ App ]
})
export class AppModule {}
detail.component.ts
// detail component
import {Component, Input, Output, EventEmitter} from '@angular/core'
@Component({
selector: 'my-detail',
template: `
<div class="column detail">
<h2>Detail</h2>
<ul>
<li>name: {{selected.name}}</li>
<li>job: {{selected.job}}</li>
<li>shift: {{selected.nocturnal ? 'Night':'Day'}}</li>
<li><button (click)="toggleShift()">Change Shift</button></li>
</ul>
</div>
`,
})
export class Detail {
@Input() selected: any;
@Output() shiftChange = new EventEmitter<any>();
toggleShift() {
this.selected.nocturnal = !this.selected.nocturnal;
this.shiftChange.emit(this.selected);
}
}
list.component.ts
// list component
import {Component, Input, OnInit, OnChanges, SimpleChange} from '@angular/core'
@Component({
selector: 'my-list',
template: `
<div class="column list">
<h2>List</h2>
<h3>Day Shift</h3>
<ul>
<li *ngFor="let item of listDay" class="{{ item.nocturnal ? 'night':'day'}}">{{ item.name }}</li>
</ul>
<h3>Night Shift</h3>
<ul>
<li *ngFor="let item of listNight" class="{{ item.nocturnal ? 'night':'day'}}">{{ item.name }}</li>
</ul>
</div>
`,
})
export class List implements OnInt, OnChanges{
@Input() list: any;
listNight:any;
listDay:any;
ngOnInit() {
this.listNight = this.list.filter(item => item.nocturnal);
this.listDay = this.list.filter(item => !item.nocturnal);
}
ngOnChanges(change: SimpleChange) {
for (let prop in change) {
if (prop === 'list') {
let list = change[prop];
this.listNight = list.currentValue.filter(item => item.nocturnal);
this.listDay = list.currentValue.filter(item => !item.nocturnal);
}
}
}
}
您可以进一步修改文件以进行优化。但是这将为您提供一个良好的开端,因为我只专注于为您的plunker提供功能。 (证实这在plunker本地工作)。希望它有所帮助。