Angular 2 ES6/7 Eventemitter 更新其他组件
Angular 2 ES6/7 Eventemitter update other Component
我想在组件之间共享数据,所以我实现了一个具有 EventEmitter 的服务。
我的服务是这样的:
@Injectable()
export class LanguageService {
constructor() {
this.languageEventEmitter = new EventEmitter();
this.languages = [];
this.setLanguages();
}
setLanguages() {
var self = this;
axios.get('/api/' + api.version + '/' + api.language)
.then(function (response) {
_.each(response.data, function (language) {
language.selected = false;
self.languages.push(language);
});
self.languageEventEmitter.emit(self.languages);
})
.catch(function (response) {
});
}
getLanguages() {
return this.languages;
}
toggleSelection(language) {
var self = this;
language.selected = !language.selected;
self.languages.push(language);
self.languageEventEmitter.emit(self.languages);
}
}
我必须要订阅这样的服务的组件:
self.languageService.languageEventEmitter.subscribe((newLanguages) => {
_.each(newLanguages, function (language) {
self.updateLanguages(language);
});
});
加载两个组件后,语言数组将按我的意愿填充。
这是第一个组件:
export class LanguageComponent {
static get parameters() {
return [[LanguageService]];
}
constructor(languageService) {
var self = this;
this.languageService = languageService;
this.languages = [];
this.setLanguages();
}
setLanguages() {
var self = this;
self.languageService.languageEventEmitter.subscribe((newLanguages) => {
_.each(newLanguages, function (language) {
self.updateLanguages(language);
})
});
}
updateLanguages(newLanguage) {
var self = this;
if (!newLanguage) {
return;
}
var match = _.find(self.languages, function (language) {
return newLanguage._id === language._id;
});
if (!match) {
self.languages.push(newLanguage);
}
else {
_.forOwn(newLanguage, function (value, key) {
match[key] = value;
})
}
toggleLanguageSelection(language) {
var self = this;
self.languageService.toggleSelection(language)
}
}
当 LanguageComponent 执行由点击事件触发的函数 toggleLanguageSelection() 时,另一个组件,订阅是这样的:
self.languageService.languageEventEmitter.subscribe((newLanguages) => {
_.each(newLanguages, function (language) {
self.updateLanguages(language);
})
});
没有收到更改通知。我认为发生这种情况是因为两个组件都获得了我的 LanguageService 的不同实例,但我不确定。我也尝试创建一个单例,但是 angular'2 di 不再起作用了。这个问题的原因是什么,我该如何解决?
您需要在引导应用程序时定义共享服务:
bootstrap(AppComponent, [ SharedService ]);
并且不再在组件的 providers
属性中定义它。这样您将拥有整个应用程序的单个服务实例。组件可以利用它一起通信。
这是因为 Angular2 的 "hierarchical injectors" 特性。详情请看这个问题:
- What's the best way to inject one service into another in angular 2 (Beta)?
我想在组件之间共享数据,所以我实现了一个具有 EventEmitter 的服务。
我的服务是这样的:
@Injectable()
export class LanguageService {
constructor() {
this.languageEventEmitter = new EventEmitter();
this.languages = [];
this.setLanguages();
}
setLanguages() {
var self = this;
axios.get('/api/' + api.version + '/' + api.language)
.then(function (response) {
_.each(response.data, function (language) {
language.selected = false;
self.languages.push(language);
});
self.languageEventEmitter.emit(self.languages);
})
.catch(function (response) {
});
}
getLanguages() {
return this.languages;
}
toggleSelection(language) {
var self = this;
language.selected = !language.selected;
self.languages.push(language);
self.languageEventEmitter.emit(self.languages);
}
}
我必须要订阅这样的服务的组件:
self.languageService.languageEventEmitter.subscribe((newLanguages) => {
_.each(newLanguages, function (language) {
self.updateLanguages(language);
});
});
加载两个组件后,语言数组将按我的意愿填充。
这是第一个组件:
export class LanguageComponent {
static get parameters() {
return [[LanguageService]];
}
constructor(languageService) {
var self = this;
this.languageService = languageService;
this.languages = [];
this.setLanguages();
}
setLanguages() {
var self = this;
self.languageService.languageEventEmitter.subscribe((newLanguages) => {
_.each(newLanguages, function (language) {
self.updateLanguages(language);
})
});
}
updateLanguages(newLanguage) {
var self = this;
if (!newLanguage) {
return;
}
var match = _.find(self.languages, function (language) {
return newLanguage._id === language._id;
});
if (!match) {
self.languages.push(newLanguage);
}
else {
_.forOwn(newLanguage, function (value, key) {
match[key] = value;
})
}
toggleLanguageSelection(language) {
var self = this;
self.languageService.toggleSelection(language)
}
}
当 LanguageComponent 执行由点击事件触发的函数 toggleLanguageSelection() 时,另一个组件,订阅是这样的:
self.languageService.languageEventEmitter.subscribe((newLanguages) => {
_.each(newLanguages, function (language) {
self.updateLanguages(language);
})
});
没有收到更改通知。我认为发生这种情况是因为两个组件都获得了我的 LanguageService 的不同实例,但我不确定。我也尝试创建一个单例,但是 angular'2 di 不再起作用了。这个问题的原因是什么,我该如何解决?
您需要在引导应用程序时定义共享服务:
bootstrap(AppComponent, [ SharedService ]);
并且不再在组件的 providers
属性中定义它。这样您将拥有整个应用程序的单个服务实例。组件可以利用它一起通信。
这是因为 Angular2 的 "hierarchical injectors" 特性。详情请看这个问题:
- What's the best way to inject one service into another in angular 2 (Beta)?