简体   繁体   English

可通过http.get观察到Angular 4 Update

[英]Angular 4 Update observable via http.get

I'm trying to update an observable which is returned in html from an API call. 我正在尝试更新从API调用以html返回的observable。

I'm wondering if anyone can help me with this. 我想知道是否有人可以帮助我。

The html (on another component) html(在另一个组件上)

<common-content [theme]="theme" ></common-content>

and the component is: 该组件是:

import { Component, OnInit, Input } from '@angular/core';
import { Http, Response } from '@angular/http';
import { ThemeModel } from '../../models';
import 'rxjs/add/operator/toPromise';

@Component({
  selector: 'common-content',
  template: `<div innerHTML = "{{innerHtml}}"></div>`
})

export class CommonContentComponent implements OnInit {
    @Input() page: string;
    @Input() theme: ThemeModel;
    innerHtml: string;

    constructor(private http: Http) {
    }

    ngOnInit() {
        this.populatePage();
    }

    populatePage(){
        let thisUrl = 'myPage.html';
        this.http.get(thisUrl).subscribe(f => {
            var content = <string>f['_body'];
            this.innerHtml = content.replace("{{theme.Name}}", this.theme.name);
            }, (error) => {
                let e = error;
            }, () => {
        });
    }
}

so instead of doing a "replace" the observable should just update automatically. 因此,可观察对象应该执行自动更新,而不是执行“替换”操作。

I've tried to use a subscribe and I also tried a promise, however I don't seem to be able to get the syntax to behave. 我尝试使用订阅,也尝试了promise,但是我似乎无法使语法表现出来。

Can anyone help? 有人可以帮忙吗?

Thanks in advance 提前致谢

1) What you want to achieve is not clear. 1)您要实现的目标尚不清楚。 What I can make out is on success you want to update the dom. 我能确定的是,您想更新dom成功。 2) Dont use inner html for that and use interpolation or ngModel for the same with a sanitizer. 2)请勿为此使用内部html,而将内插法或ngModel与消毒剂一起使用。 3) Another approach would be to create a custom reusable directive for the same. 3)另一种方法是为其创建自定义可重用指令。

An approach could be: 一种方法可以是:

1) Make a pipe for sanitization: 1)制作管道进行消毒:

import { Pipe, PipeTransform } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';
/**
 *
 * @export
 * @class SafeHtmlPipe
 * @implements {PipeTransform}
 */
@Pipe({
  name: 'safeHtml'
})
export class SafeHtmlPipe implements PipeTransform {
  /**
   *
   * @param {DomSanitizer} sanitizer
   * @memberof SafeHtmlPipe
   */
  constructor(private sanitizer: DomSanitizer) { }
  /**
   *
   * @param {any} style
   * @returns
   * @memberof SafeHtmlPipe
   */
  transform(style) {
    // return this.sanitizer.bypassSecurityTrustStyle(style);
    return this.sanitizer.bypassSecurityTrustHtml(style);
    // return this.sanitizer.bypassSecurityTrustXxx(style); - see docs
  }
}

2) Use it like : 2)像这样使用它:

<div class="card_description" [innerHTML]="scenarioStepDataDesc | safeHtml"></div>

where scenarioStepDataDesc is your HTML content. 其中方案StepDataDesc是您的HTML内容。

3) Use a shared module for pipes and other reusable components/directives 3)将共享模块用于管道和其他可重复使用的组件/指令

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { MaterialModule } from '../material/material.module';
import { BlockUIModule } from 'ng-block-ui';
import { AutoCompleteComponent } from './components/autoComplete/autoComplete.component';
import { DialogDataComponent } from './components/dialog/dialog.component';
import { SafeHtmlPipe } from './pipes/safeHtml.pipe';
/**
 *
 * @export
 * @class SharedModule
 */
@NgModule({
  imports: [CommonModule, FormsModule, MaterialModule, BlockUIModule, ReactiveFormsModule],
  exports: [
    CommonModule,
    FormsModule,
    MaterialModule,
    BlockUIModule,
    ReactiveFormsModule,
    AutoCompleteComponent,
    DialogDataComponent,
    SafeHtmlPipe
  ],
  declarations: [AutoCompleteComponent, DialogDataComponent, SafeHtmlPipe]
})
export class SharedModule { }

Enjoy :) 请享用 :)

I suggest you update your <string> f['_body']; 我建议您更新您的<string> f['_body']; change to <string>f.text() , and also innerHTML = "{{innerHtml}}" to [innerHTML]="view" anyway check the below plnkr link as it's doing exactly what you are trying to perform 更改为<string>f.text() ,也将innerHTML = "{{innerHtml}}"更改为[innerHTML]="view" ,因为它确实在执行您要执行的操作,因此请检查下面的plnkr链接

this._http.get(link).subscribe(f => {
     this.loading = false;
            var content = <string>f.text();
            this.view = content.replace("{{theme.Name}}", this.theme.name);
            }, (error) => {
              this.loading = false;
              console.error(error);
                alert(error);
            });

the template is like this 模板是这样的

content <button (click)="open('external.html')">Open Page</button>
      <strong *ngIf="loading">LOADING...</strong>
      <div [innerHTML]="view"></div>

the external.html is simple as below external.html很简单,如下所示

me playing around with this theme with name 
<b>
  {{theme.Name}}
</b>

here is the running Plnkr 这是正在运行的Plnkr

But for String interpolation processing as if the content was in the same template as the parent loading it and bind this to the template scope, which is similar to angular 1 ng-include check this answer as it helps in solving that (instead of re doing it), and note this is for angular 4 and above 但对于字符串插值处理,如果内容是相同的模板,因为父加载它,并绑定this到模板的范围,这是类似角1 纳克,包括检查这个答案 ,因为它有助于在解决了(而不是重新做),请注意,这是针对角度4及以上

using Angular 4.0.0-beta.6's ngComponentOutlet . 使用Angular 4.0.0-beta.6的ngComponentOutlet

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM