任何人都可以帮我看看我的模板中是否存在语法错误?它不会给出错误,但不会将数据填入模板:
<div *ngIf="(hero | async)">
<h2>{{hero}}</h2>
<h2>{{hero.name}} details!</h2>
<div>
<label>_id: </label>{{hero._id}}</div>
<div>
<label>name: </label>
<input [(ngModel)]="hero.name" placeholder="name" />
</div>
<button (click)="goBack()">Back</button>
</div>
组件代码
export class HeroDetailComponent implements OnInit {
errorMessage: string;
//@Input()
hero: Observable<Hero>;
constructor(
private _heroService: HeroService,
private _routeParams: RouteParams) {
}
ngOnInit() {
let _id = +this._routeParams.get('_id');
this._heroService.loadHero(_id);
this.hero = this._heroService.hero$;
this.hero.subscribe(data =>
console.log(data)
)
}
console.log(data)
打印:
对象{_id:11,名称:“尼斯先生”}
表示正确检索数据。
<div>
块也会显示,这意味着*ngIf
会将对象视为非空。
<h2>{{hero}}</h2>
显示[object Object]
。
但为什么{{hero.name}}
没有显示?
答案 0 :(得分:58)
使用异步管道对象有点棘手。使用包含数组的Observable,我们可以使用NgFor并创建一个本地模板变量(下面为hero
),在异步管道从Observable中提取数组后,该变量将被赋予数组的每个项目。然后我们可以在模板的其他地方使用该变量:
<div *ngFor="let hero of heroes | async">
{{hero.name}}
</div>
<!-- we can't use hero here, outside the NgFor div -->
但是对于包含单个对象的Observable,我不知道有任何方法可以创建引用该对象的本地模板变量。相反,我们需要做一些更复杂的事情:
<div>{{(hero | async)?.name}}</div>
我们需要对要显示的对象的每个属性重复这一点。 (上面的行假定组件属性hero
是一个Observable。)
使用组件逻辑将对象(在Observable中,hero$
内部)分配给组件的属性可能更容易:
this._heroService.hero$.subscribe(data => this.hero = data.json());
然后使用NgIf或Elvis/safe navigation operator在视图中显示数据:
<div *ngIf="hero">{{hero.name}}</div>
<!-- or -->
<div>{{hero?.name}}</div>
答案 1 :(得分:21)
另一个选择是使用@Input并利用智能/哑元组件方法。在智能组件中,您可以将异步对象传递给哑组件,然后在哑组件中将其用作普通对象。
这个想法是你的智能组件处理逻辑和数据,而哑组件处理表示。
智能组件:
<dumb-component [myHero]="hero$ | async"></dumb-component>
哑组件类:
@Input() myHero: Hero;
哑组件模板:
<div>{{ myHero.name }}</div>
答案 2 :(得分:17)
现在可以使用v4.0.0中提供的'as'语法:
<span *ngIf="user$ | async as user; else loadingUserInfo">
{{user.firstName}} {{user.lastName}}
</span>
<ng-template #loadingUserInfo>
Loading user information...
</ng-template>
RFC thread on github中提供了更多详细信息。
答案 3 :(得分:1)
我只是在需要使用异步管道和括号语法的情况下,添加一个关于如何使用智能/哑组件方法的精度。
结合发现here的技巧。
< ui-gallery-image([image]="(imagesFB | async) ? (imagesFB | async)[0] : null") ></ui-gallery-image>
我花了好几个小时才找到。希望这有帮助。 有关此blog post的更多信息。
答案 4 :(得分:1)
在Angular 2.3.x或Angular 4.x模板中处理 Single Observable Object 的最佳方法是使用带模板变量的异步管道。
这是角度开发人员的共同目标。从redux中获取一系列元素,并从集合中获取单个匹配元素。然后在模板中渲染该单个对象。
COMPONENT
@Component({
selector: 'app-document-view',
templateUrl: './document-view.component.html',
styleUrls: ['./document-view.component.scss']
})
export class DocumentViewComponent implements OnInit {
@select(['documents', 'items']) readonly documenList$: Observable<DocumentDTO[]>;
public documentVO$: Observable<DocumentDTO>;
constructor(private _state: NgRedux<IAppState>,
private _route: ActivatedRoute,
private _documentActions: DocumentActions) {
_route.params.subscribe(params => {
let modelId: number = parseInt(params['modelId']); //1
let documentId: number = parseInt(params['documentId']); //50
this._documentActions.getDocument(modelId, documentId);
});
}
ngOnInit() {
//documenList holds all of the documents in our application state
//but this view only wants a single element
this.documentVO$ = this.documenList$.map(documents => documents.find(doc => doc.documentId === 50));
}
}
查看
<div class="row" *ngIf="documentVO$ | async as dto">
<div id="about" class="col-12">
<div id="title" class="paper meta">
<p>{{ dto.title }}</p>
</div>
</div>
</div>
答案 5 :(得分:0)
异步管道订阅
取消订阅
为 OnPush 调用 markForCheck()
@组件({ 选择器:'product-alt', templateUrl: './products-alt.component.html', changeDetection: ChangeDetectionStrategy.OnPush }) 导出类 ProductAltComponent 实现 OnDestroy { 页面标题:字符串 = ''; pageTitle$ = (new BehaviorSubject('InitialTitle'));
constructor(private cdr: ChangeDetectorRef) {
//Asyc pipe subscribs
this.pageTitle$.subscribe((title: string) => {
this.pageTitle = title;
// call markForCheck
this.cdr.markForCheck()
});
}
ngOnDestroy() {
//Unsubscrib
this.pageTitle$.unsubscribe();
}