Angular 将属性公开为可观察属性的最简单语法?
我已经看过很多教程,展示了无数种不同的方法来实现角度观测。就我的目的而言,其中许多似乎过于复杂。其他版本适用于以前的版本,不再适用 假设我有一个名为Angular 将属性公开为可观察属性的最简单语法?,angular,typescript,angular-observable,Angular,Typescript,Angular Observable,我已经看过很多教程,展示了无数种不同的方法来实现角度观测。就我的目的而言,其中许多似乎过于复杂。其他版本适用于以前的版本,不再适用 假设我有一个名为numChickens的单一属性的服务,我希望允许组件订阅该属性。真的((需要)=>to.chain((a)=>{million.garbledyGook().statements.to('gether)})让它工作吗 以下是有关服务的代码: import { Injectable } from '@angular/core'; @Injectab
numChickens
的单一属性的服务,我希望允许组件订阅该属性。真的((需要)=>to.chain((a)=>{million.garbledyGook().statements.to('gether)})让它工作吗
以下是有关服务的代码:
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class ChickenService {
public chickens: number;
constructor() { }
}
…以下是使用可观察组件的代码:
import { Component, OnInit } from '@angular/core';
import { ChickenService } from '../chicken.service';
@Component({
selector: 'app-chickendisplay',
templateUrl: './chickendisplay.component.html',
styleUrls: ['./chickendisplay.component.scss']
})
export class ChickenDisplayComponent implements OnInit {
constructor(public cs: ChickenService) {
}
ngOnInit() {
}
}
在Angular 6中,什么是最简单、最直接、最可读的方法来公开ChickenService中的属性
,以便组件类可以访问该属性的值作为可观察流?或者组件模板可以使用异步管道显示该值
我再怎么强调也不为过——请不要回答包含8192个字符的闭包,然后说“看,这很简单”
我问这个问题不仅仅是为了我自己,也是为了像我这样的其他人,他们正试图把他们的脑袋绕到可观测的物体上,并与所有关于这个主题的密集和过时的教程作斗争。如果你能将这个解决方案简化为一个简单的形式,后代将感谢你。如果你真的想将它作为一个流公开,你所需要做的一切要做的是添加一行:
import { Injectable } from '@angular/core';
import { of } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class ChickenService {
public chickens: number;
public chickens$ = of(chickens);
constructor() { }
}
注意,这样做仍然不允许您更新值,因此这样做没有多少附加值
您可以使用主题来更新值,并通过订阅流在UI中反映这些更改:
import { Injectable } from '@angular/core';
import { of } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class ChickenService {
public chickens: number;
public chickens$ = chickensSub$.asObservable();
private chickensSub$ = new BehaviorSubject();
constructor() { }
updateChickens(value: number) {
this.chichensSub$.next(value);
}
}
注意:我尽量避免在不必要时显式使用主题。最简单的方法是创建一个私有的
主题,并使用它来创建公共的可观察的
在下面的代码中,我为您的checks
变量创建了get
和set
。这意味着每次使用(例如)service.chicks=10
更新它时,它都会用新值自动触发可观察的流上的新事件
import { Injectable } from '@angular/core';
import { Subject, Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class ChickenService {
private _chickens: number; // Make this private so we can expose it via a get/set
private chickenChange$ = new Subject<number>(); // This will be used to create our Observable
public chickens$ = this.chickenChange$.asObservable(); // This is our Observable
constructor() { }
set chickens(val: number) {
this._chickens = val; // Set the new value
this.chickenChange$.next(val); // Trigger the subject, which triggers the Observable
}
get chickens() {
return this._chickens;
}
}
从'@angular/core'导入{Injectable};
从“rxjs”导入{Subject,observeable};
@注射的({
providedIn:'根'
})
出口级小鸡服务{
private _:number;//将此设置为私有,以便我们可以通过get/set公开它
private chickenChange$=new Subject();//这将用于创建可观察的
公共鸡$=this.chickenChange$.asObservable();//这是我们可以观察到的
构造函数(){}
集鸡(val:数量){
此。_=val;//设置新值
this.chickenChange$.next(val);//触发主题,该主题触发可观察对象
}
养鸡{
把这个还给我;
}
}
你可以考虑使用一个装饰器来把一个属性变成可观察的。这样做的细节并不特别有趣,但是一旦你完成了,你就可以写下类似的东西:
export class ChickenService {
@Observablize()
public chickens: number;
public chickens$: Observable<number>;
}
导出类ChickenService{
@可观察()
公众鸡只:数目;
公鸡:可见;
}
好的,现在深吸一口气。下面是装饰器实现的大致情况(未经测试)
函数Observalize(){
返回函数(目标,propertyKey:string,描述符:PropertyDescriptor){
const observekey=propertyKey+“$”;
const privateKey=propertyKey+“389;”;
Object.defineProperties(target.prototype{
[ObserveKey]:{value:new Subject()},
[propertyKey]:{
get(){返回此[privateKey];},
set(v){this[privateKey]=v;this[observeKey].next(v);}
}
});
};
}
什么是可观察的()
do,为什么需要它呢?我以为Subject
s已经是可观察的了。@torazaburoSubject
s是可观察的
s,但他们也是观察者
s。通过一个可观察的
来公开它,这意味着我们服务之外的任何东西都不能触发该流上的事件。他们可以听,但是他们不会写字吗
function Observablize() {
return function (target, propertyKey: string, descriptor: PropertyDescriptor) {
const observableKey = propertyKey + "$";
const privateKey = propertyKey + "_";
Object.defineProperties(target.prototype, {
[observableKey]: { value: new Subject<any>() },
[propertyKey]: {
get() { return this[privateKey]; },
set(v) { this[privateKey] = v; this[observableKey].next(v); }
}
});
};
}