Asynchronous 角度2-使用异步http请求的插值和绑定

Asynchronous 角度2-使用异步http请求的插值和绑定,asynchronous,binding,httprequest,angular,string-interpolation,Asynchronous,Binding,Httprequest,Angular,String Interpolation,我是Angular 2的新手,我面临着异步http请求和插值绑定的问题 以下是我的组件: @组件({ 选择器:“信息”, 模板:`{model.Name}}` }) 导出类InfoComponent实现OnInit{ 型号:任意; 建造师( 专用服务:后端服务 ) { } 恩戈尼尼特(){ if(this.model==null){ this._service.observateModel$.subscribe(m=>this.model=m); 此._service.get(); }

我是Angular 2的新手,我面临着异步http请求和插值绑定的问题

以下是我的组件:

@组件({
选择器:“信息”,
模板:`{model.Name}}`
})
导出类InfoComponent实现OnInit{
型号:任意;
建造师(
专用服务:后端服务
) { }
恩戈尼尼特(){
if(this.model==null){
this._service.observateModel$.subscribe(m=>this.model=m);
此._service.get();
}     
}
}
当呈现模板时,我得到一个错误,因为“model”尚未设置

我用这个非常丑陋的黑客解决了这个问题:

@组件({
选择器:“信息”,
模板:`
{{model.Name}
`
})
导出类NeadInfoComponent实现OnInit{
模型:可观察;
建造师(
专用服务:后端服务
) { }
恩戈尼尼特(){
if(this.models==null){
this._service.observableModel$.subscribe(m=>this.models=Observable.of([m]);
此._service.get();
}     
}
}
我的问题是:如何延迟模板呈现直到我的http调用完成,或者如何直接在模板中插入“model”值而不绑定到另一个组件


谢谢

本讨论列出了一些策略

这个问题有很多含义。在某些情况下,应在框架之外管理可观察对象

你可以在引导之前扫描所有的观测值

B.引导然后在将对象传递给顶级组件之前扫描所有可观察对象

C.您还可以将组件内的changeDetection更改为在输入更改时触发或手动触发更改检测器

D.如果您使用的是| async,那么只有在您不想使用.subscribe的情况下,才应该在顶层使用它,但实际上您应该只使用.subscribe

E.如果你在任何地方都使用| async,那么你真正要做的就是将渲染控制权倒置到可观察对象上,这意味着我们又回到了级联变化的角度1天,因此你要么需要执行C、D、B或A

目前似乎不起作用。您可以简单地将组件设置为分离

我们还可以使用ngoninitlifecyclehook从变更检测树中删除组件。您需要运行此.ref.detach();其中ref通过ChangeDetectorRef注入

ngOnInit(){
这个.ref.detach();
}
makeYourChanges(){
this.ref.reattach();//附加回更改检测器树
this.data.value=Math.random()+“”;//进行更改
this.ref.detectChanges();//检查为脏
this.ref.detach();//从树中删除
//zone.js触发更改
}

您也不能包含zone.js并手动控制所有更改。您还可以注入NgZone在zone.js之外运行操作,这样它就不会告诉angular触发通道。比如说,

//此示例可能需要重构才能使用rxjs 5
导出类时间表{
pos=‘绝对’;
颜色=红色;
字母:LetterConfig[];
建造师(
私人服务:信息,
二等兵el:ElementRef,
私人专区:NgZone){
}
恩戈尼尼特(){
//初始映射(鼠标移动前)
this.letters=this.service.message.map(
(val,idx)=>({
文本:val,
前100名,
左:(idx*20+50),
索引:idx
})
);
此.zone.runOutsideAngular(()=>{
可观察
.fromEvent(此.el.nativeElement“mousemove”)
.map((e:MouseEvent)=>{
//var offset=getOffset(this.el);
//减去元素的偏移量
var o=this.el.nativeElement.getBoundingClientRect();
返回{
偏移量:e.clientX-o.left,
副词:e.clientY-o.top
};
})
.flatMap(增量=>{
可观测回波
.fromArray(此为.letters
.map((val,index)=>({
信:val.text,
三角洲,
指数
})));
})
.flatMap(letterConfig=>{
可观测回波
.timer((letterConfig.index+1)*100)
.map(()=>({
文本:letterConfig.letter,
顶部:letterConfig.delta.offsetY,
左:letterConfig.delta.offsetX+letterConfig.index*20+20,
索引:lettconfig.index
}));
})
.subscribe(letterConfig=>{
//要渲染字母,请将它们放回应用程序区域
this.zone.run(()=>this.letters[letterConfig.index]=letterConfig);
});
});//区域
}
}

如果要从服务器返回对象,可以使用模板中的(?):

@Component({
  selector: 'info',
  template: `<h1>{{model?.Name}}</h1>`
})
export class InfoComponent implements OnInit {
    model: any;
    constructor(private _service: BackendService) { }

    ngOnInit() {
       this._service.getData().subscribe(m => this.model = m);
       // getData() looks like the following:
       //    return this._http.get('....')  // gets JSON document
       //       .map(data => data.json()); 
    }
}
@组件({
选择器:“信息”,
模板:`{model?.Name}}`
})
导出类InfoComponent实现OnInit{
型号:任意;
构造函数(私有_服务:后端服务){}
恩戈尼尼特(){
this._service.getData().subscribe(m=>this.model=m);
//getData()如下所示:
//返回此内容。_http.get('..')//获取JSON文档
//.map(data=>data.json());
}
}

请参阅以获取可用的工具。

谢谢Mark!猫王成功了!但我还不了解渲染流程。每次组件属性发生任何更改时都会呈现模板?@TonyAlexanderHild,在角度更改检测期间(在每个事件之后运行),默认情况下,所有视图/模板绑定都会被脏检,这意味着它们会被检查更改。当数据从服务器返回时,这是一个事件,因此会运行更改检测
model.Name
已被脏检查并发现已更改,因此Angular将更新DOM。角度控制后返回到眉毛