如何防止组件更新服务
How to prevent component from updating service
我是 Angular 4 的新手,我正在尝试设置一个服务,其中包含一些数据,这些数据不应被它提供数据的任何组件编辑。例如,这是我的服务的简化版本:
@Component({
providers: [ArgumentService]
})
@Injectable()
export class ArgumentService {
pronouns: Object[];
constructor() {
this.pronouns = [{'type': "1SG", 'value': 'n', "series": "I"},
{'type': "2SG", 'value': 'm', "series": "I"},
{'type': "1SG", 'value': "'y", "series": "II"},
{'type': "2SG", 'value': 'n', "series": "II"},
{'type': "1SG", 'value': "'nii'y", "series": "III"},
{'type': "2SG", 'value': "'niin", "series": "III"}];
}
getPronouns(){
return this.pronouns
}
}
对象数组不应更改。但是,下面组件中的示例函数更改了数组中的第一个对象:
import { Sentence } from '../sentence.model'
import { VerbService, ArgumentService } from '../../services/'
import { RadioButtonComponent } from '../radio-button/radio-button.component'
@Component({
selector: 'app-sentence',
templateUrl: './sentence.component.html',
styleUrls: ['../../bootstrap.min.css', './sentence.component.scss', '../app.component.scss'],
providers: [VerbService, ArgumentService]
})
export class SentenceComponent implements OnInit {
constructor(public verbService: VerbService, public argumentService: ArgumentService) {
this.example()
}
example(){
let arg = this.argumentService.getPronouns()[0]
arg['position'] = 'S'
console.log(this.argumentService.getPronouns()) // this gives {'type': "1SG", 'value': 'n', "series": "I", "position": "S"} when it should give {'type': "1SG", 'value': 'n', "series": "I"}
}
ngOnInit() {
}
}
也许我认为这种数据应该放在服务中是错误的?服务是否总是应该从其组件更新?如果有任何建议或指导,我将不胜感激。
提前致谢。
getPronouns(){
return this.pronouns.map(p => Object.assign({}, p))
}
这将 return 不仅是数组的副本,而且是其所有内容的副本。 (我之前的尝试,this.pronouns.slice(),复制数组但用对相同对象的引用填充它)
发生这种情况是因为对象是可变的并且通过引用传递。如果你想避免这种情况,使用 Observables,在这种情况下 BehaviorSubject
是合适的。为您服务:
import {BehaviorSubject} from 'rxjs/BehaviorSubject';
// ...
pronounsArr = [....];
// don't use 'any', type your data! :)
private pronouns: BehaviorSubject<any[]>
= new BehaviorSubject<any[]>(this.pronounsArr);
public pronouns$ = this.pronouns.asObservable();
然后在组件中,你可以订阅这个observable:
constructor (
public verbService: VerbService,
public argumentService: ArgumentService
) {
argumentService.pronouns$.subscribe(pronouns => {
console.log(pronouns)
// do whatever you like...
})
}
我是 Angular 4 的新手,我正在尝试设置一个服务,其中包含一些数据,这些数据不应被它提供数据的任何组件编辑。例如,这是我的服务的简化版本:
@Component({
providers: [ArgumentService]
})
@Injectable()
export class ArgumentService {
pronouns: Object[];
constructor() {
this.pronouns = [{'type': "1SG", 'value': 'n', "series": "I"},
{'type': "2SG", 'value': 'm', "series": "I"},
{'type': "1SG", 'value': "'y", "series": "II"},
{'type': "2SG", 'value': 'n', "series": "II"},
{'type': "1SG", 'value': "'nii'y", "series": "III"},
{'type': "2SG", 'value': "'niin", "series": "III"}];
}
getPronouns(){
return this.pronouns
}
}
对象数组不应更改。但是,下面组件中的示例函数更改了数组中的第一个对象:
import { Sentence } from '../sentence.model'
import { VerbService, ArgumentService } from '../../services/'
import { RadioButtonComponent } from '../radio-button/radio-button.component'
@Component({
selector: 'app-sentence',
templateUrl: './sentence.component.html',
styleUrls: ['../../bootstrap.min.css', './sentence.component.scss', '../app.component.scss'],
providers: [VerbService, ArgumentService]
})
export class SentenceComponent implements OnInit {
constructor(public verbService: VerbService, public argumentService: ArgumentService) {
this.example()
}
example(){
let arg = this.argumentService.getPronouns()[0]
arg['position'] = 'S'
console.log(this.argumentService.getPronouns()) // this gives {'type': "1SG", 'value': 'n', "series": "I", "position": "S"} when it should give {'type': "1SG", 'value': 'n', "series": "I"}
}
ngOnInit() {
}
}
也许我认为这种数据应该放在服务中是错误的?服务是否总是应该从其组件更新?如果有任何建议或指导,我将不胜感激。
提前致谢。
getPronouns(){
return this.pronouns.map(p => Object.assign({}, p))
}
这将 return 不仅是数组的副本,而且是其所有内容的副本。 (我之前的尝试,this.pronouns.slice(),复制数组但用对相同对象的引用填充它)
发生这种情况是因为对象是可变的并且通过引用传递。如果你想避免这种情况,使用 Observables,在这种情况下 BehaviorSubject
是合适的。为您服务:
import {BehaviorSubject} from 'rxjs/BehaviorSubject';
// ...
pronounsArr = [....];
// don't use 'any', type your data! :)
private pronouns: BehaviorSubject<any[]>
= new BehaviorSubject<any[]>(this.pronounsArr);
public pronouns$ = this.pronouns.asObservable();
然后在组件中,你可以订阅这个observable:
constructor (
public verbService: VerbService,
public argumentService: ArgumentService
) {
argumentService.pronouns$.subscribe(pronouns => {
console.log(pronouns)
// do whatever you like...
})
}