我有一个简单的css animation库,允许通过调用loadService.animate(boolean);
来显示动画,但遗憾的是它不再起作用,因为我在我的服务中错误地使用了EventEmitter
这样:
@Injectable()
export class LoadService {
@Output() animating: EventEmitter<any> = new EventEmitter();
constructor() {}
// User calls animate, we emit an event with the new boolean value
public animate(val: boolean) {
this.animating.emit(val);
}
getValue(): any {
return this.animating;
}
}
在我的组件中订阅它:
// Animation shown when animate == true
animate: boolean;
ngOnInit(): void {
this.loadService.getValue().subscribe((status: boolean) => {
// Events caught, we change the boolean to display the animation
this.animate = status;
});
this.handleShape();
}
但是我的订阅从未捕获任何内容,所以我想我想创建自定义Observable
,以便在用户调用animate
时捕获并因此更改值我的布尔值。
如何在Angular2 +中定义自定义observable?我如何在这种情况下实现它?
答案 0 :(得分:2)
在我们的服务中,我们创建了一个BehaviorSubject
,其默认值为false
:
private _animate = BehaviorSubject(false);
get animate(): Observable<any>{
return this._animate.asObservable();
}
另外,在LoadService
中,要更新我们的observable
值:
toggleAnimation(value: boolean){
oldValue = this._animate.getValue();
this._animate.next(!oldValue);
}
现在在我们的组件中,您可以像这样订阅它:
constructor(private service: LoadService) {
this.service.animate.subscribe(state => {
// do stuff
console.log(state);
})
};
答案 1 :(得分:0)
Angular团队不鼓励在服务中使用eventemitter,因为它被用作围绕主题的抽象。您可以通过使用新的关键字来创建具有自定义逻辑的observable,并提供发射的逻辑,或者您可以使用Subject(一个可观察的和观察者),将其视为观察者模式的最相似的实现
function importData() {
var fSource = DriveApp.getFolderById("0ByXeCX01JfKJN1dTNk1SRlQyb1k"); // reports_folder_id = id of folder where csv reports are saved
var fi = fSource.getFilesByName('201707160600070685.csv'); // latest report file
var ss = SpreadsheetApp.openById("1T2JU4KwpJsnlJk0LOEZoHr9uqnNrVYwBWI1NxOwL4PU"); // data_sheet_id = id of spreadsheet that holds the data to be updated with new report data
if ( fi.hasNext() ) { // proceed if "report.csv" file exists in the reports folder
var file = fi.next();
var csv = file.getBlob().getDataAsString();
var csvData = CSVToArray(csv); // see below for CSVToArray function
var newsheet = ss.insertSheet("NEWDATA"); // create a 'NEWDATA' sheet to store imported data
// loop through csv data array and insert (append) as rows into 'NEWDATA' sheet
for ( var i=0, lenCsv=csvData.length; i<lenCsv; i++ ) {
newsheet.getRange(i+1, 1, 1, csvData[i].length).setValues(new Array(csvData[i]));
}
/*
** report data is now in 'NEWDATA' sheet in the spreadsheet - process it as needed,
** then delete 'NEWDATA' sheet using ss.deleteSheet(newsheet)
*/
// rename the report.csv file so it is not processed on next scheduled run
file.setName("report-"+(new Date().toString())+".csv");
}
};
将主题视为事件发射器和侦听器之间的代理,无论何时调用主题上的下一个函数,发出的值都将被推送到observable的所有订阅者。
loadServiceSubject : Subject<any> = new Subject();
loadService$ : Observable<any> = loadServiceSubject.asObservable();
// other code
“事件”发射器只需要调用主题本身的下一个,错误或完整函数。
// in client code
// suppose the service is injected in the constructor
this.animationService.loadService$.subscribe( this.doStuffOnNextCallback );