在angular中,我尝试创建一个示例服务来传递一个数组,该数组将被所有组件共同使用,然后一个组件向该数组添加新元素。但是,在推送它之后,新元素不会在app.component.html中呈现。我对角度有点新意。请帮忙。 app.component.html是:
<div class="container">
<div class="row">
<div class="col-xs-12 col-md-8 col-md-offset-2">
<app-new-account></app-new-account>
<hr>
<app-account
*ngFor="let acc of myAccounts; let i = index"
[account]="acc"
[id]="i"></app-account>
</div>
</div>
</div>
app.component.ts是:
import { Component, OnInit } from '@angular/core';
import { AccountsService } from './accounts.service';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
providers: [AccountsService]
})
export class AppComponent implements OnInit {
myAccounts: {name: string, status: string}[] = [];
constructor(private accountsService: AccountsService) {}
ngOnInit() {
this.myAccounts = this.accountsService.accounts;
}
}
服务(accounts.service.ts)是:
import { Injectable } from '@angular/core';
@Injectable()
export class AccountsService {
accounts = [
{
name: 'Master Account',
status: 'active'
},
{
name: 'Testaccount',
status: 'inactive'
},
{
name: 'Hidden Account',
status: 'unknown'
}
];
addAccount(acctName: string, acctStatus: string) {
console.log("inside add accnt");
this.accounts.push({name: acctName, status: acctStatus});
console.log(this.accounts);
}
updateStatus(id: number, status: string) {
this.accounts[id].status = status;
}
}
子组件account.component.html是:
<div class="row">
<div class="col-xs-12 col-md-8 col-md-offset-2">
<h5>{{ account.name }}</h5>
<hr>
<p>This account is {{ account.status }}</p>
<button class="btn btn-default" (click)="onSetTo('active')">Set to 'active'</button>
<button class="btn btn-default" (click)="onSetTo('inactive')">Set to 'inactive'</button>
<button class="btn btn-default" (click)="onSetTo('unknown')">Set to 'unknown'</button>
</div>
</div>
子组件account.component.ts是:
import { Component, Input } from '@angular/core';
import { LoggingService } from '../logging.service';
import { AccountsService } from '../accounts.service';
@Component({
selector: 'app-account',
templateUrl: './account.component.html',
styleUrls: ['./account.component.css'],
providers: [LoggingService]
})
export class AccountComponent {
@Input() account: {name: string, status: string};
@Input() id: number;
constructor(private loggingService: LoggingService, private accountsService: AccountsService) {}
onSetTo(status: string) {
this.accountsService.updateStatus(this.id, status);
this.loggingService.logStatusChange(this.account.status);
}
}
子组件new-account.component.html是:
<div class="row">
<div class="col-xs-12 col-md-8 col-md-offset-2">
<div class="form-group">
<label>Account Name</label>
<input
type="text"
class="form-control"
#accountName>
</div>
<div class="form-group">
<select class="form-control" #status>
<option value="active">Active</option>
<option value="inactive">Inactive</option>
<option value="hidden">Hidden</option>
</select>
</div>
<button
class="btn btn-primary"
(click)="onCreateAccount(accountName.value, status.value)">
Add Account
</button>
</div>
</div>
子组件new-account.component.ts是:
import { Component } from '@angular/core';
import { LoggingService } from '../logging.service';
import { AccountsService } from '../accounts.service';
@Component({
selector: 'app-new-account',
templateUrl: './new-account.component.html',
styleUrls: ['./new-account.component.css'],
providers: [LoggingService]
})
export class NewAccountComponent {
constructor(private loggingService: LoggingService, private accountsService: AccountsService) {}
onCreateAccount(accountName: string, accountStatus: string) {
this.accountsService.addAccount(accountName, accountStatus);
this.loggingService.logStatusChange(accountStatus);
}
}
答案 0 :(得分:0)
这是一个变化检测问题。您必须更改对数组的引用以触发更改检测。
在服务档案中:
#:kivy 1.10.0
#:import FadeTransition kivy.uix.screenmanager.FadeTransition
<RootScreen>:
transition: FadeTransition()
IntroScreen:
name: 'intro'
NameScreen:
name: 'data'
<IntroScreen>:
AnchorLayout:
Image:
source: 'kivyLogo.png' # 'yCFD2.png'
size_hint: 1,1
Button:
background_color: [63, 191, 63, 0.0]
text: ''
on_press: root.manager.current = 'data'
<NameScreen>:
canvas.before:
Rectangle:
pos: self.pos
size: self.size
source: 'kivymd_logo.png' # 'X6TF0.png'
FloatLayout:
TextInput:
id: ChildName
size_hint:.2, .2
pos_hint:{'x': 0.7, 'y': 0.4}
text: "Введи имя"
focus: True
multiline: False
TextInput:
id: ChildAge
size_hint:.2, .2
pos_hint:{'x': 0.7, 'y': 0.6}
text: "Введи возраст"
focus: True
multiline: False
Button:
size_hint:.2, .2
pos_hint:{'x': 0.7, 'y': 0.8}
background_color: [63, 191, 63, 0.3]
text: 'Добавить в базу'
on_press: root.PrintData(ChildName.text, ChildAge.text)
在组件文件中:
addAccount(acctName: string, acctStatus: string) {
this.accounts = [...this.accounts, {name: acctName, status: acctStatus}]
}
updateStatus(id: number, status: string) {
this.accounts = this.accounts.map((acc, i) => i === id ? { ...acc, status } : acc))
}
你应该习惯于使用不可变数据(总是返回新副本,而不是改变原始值),否则你最终会得到带有角度变化检测的奇怪错误日志。
良好的经验法则是: 如果您的console.log显示正确的值,但模板未更新,则表明存在更改检测问题。
答案 1 :(得分:0)
只要您不使用OnPush
更改检测策略,它就应该按照您的描述运行。我将你的代码复制到stackblitz中,我觉得它的工作原理是:
https://stackblitz.com/edit/angular-3dxw8d
周末愉快