【问题标题】:Angular 4 Update observable via http.get通过 http.get 可观察到的 Angular 4 更新
【发布时间】:2017-10-18 17:46:26
【问题描述】:

我正在尝试更新从 API 调用以 html 形式返回的 observable。

我想知道是否有人可以帮助我。

html(在另一个组件上)

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

组件是:

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;
            }, () => {
        });
    }
}

因此,observable 应该自动更新,而不是“替换”。

我尝试过使用订阅,也尝试过承诺,但我似乎无法让语法正常运行。

谁能帮忙?

提前致谢

【问题讨论】:

  • 你能显示f的内容吗
  • 只是一个芯片,而不是&lt;string&gt; f['_body'];更改为&lt;string&gt;f.text()更安全
  • 我不明白你在问什么。你想达到什么目的。您的代码发送一个 HTTP 请求,当响应返回时,使用响应的主体初始化组件的 innerHtml 字段(经过一些替换)。您还想实现什么目标?
  • 在模板中使用
    而不是
  • 感谢 Theophilus,我使用 f.text() 代替。我试图实现 Chandru 是不需要对返回的 html 进行替换。它将它作为一个字符串返回,而不是作为一个可用的 observable。

标签: angular typescript angular2-template angular2-observables


【解决方案1】:

1) 你想要达到的目标不明确。 我可以确定的是您想要更新 dom 是否成功。 2)不要为此使用内部html,并使用插值或ngModel与消毒剂相同。 3) 另一种方法是为其创建自定义可重用指令。

一种方法可能是:

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) 像这样使用它:

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

scenarioStepDataDesc 是您的 HTML 内容。

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 { }

享受:)

【讨论】:

  • 嗨 Shubhendu,我尝试编写一个服务,但我似乎也无法让它工作。
  • 由于不清楚,请重新定义问题陈述,然后我会尽力提供帮助。
  • 当然,问题是我从另一个页面加载了一些 html。我希望插值可以在我刚刚加载的 html 上工作,这样我就可以在视图中看到插值结果,而不是纯文本。换句话说,我在视图中看到了 {{ theme.name }},但我想在视图中看到的是在主题配置文件中配置的数据,它可能是“黄色主题”。
  • 我以前从未使用过 plnkr,但我已将大部分代码(不起作用)放在 plnkr.co/edit/X2jYniwfVs0SK7WQPMm7 中。到目前为止,我尝试过的任何方法都没有真正奏效
【解决方案2】:

我建议您将&lt;string&gt; f['_body']; 更改为&lt;string&gt;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);
            });

模板是这样的

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

external.html 很简单,如下所示

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

这是正在运行的Plnkr

但是对于字符串插值处理,就好像内容与加载它的父级在同一个模板中一样,并将this绑定到模板范围,类似于角度1 ng-include检查这个answer 因为它有助于解决这个问题(而不是重新做),请注意这是 angular 4 及以上

使用 Angular 4.0.0-beta.6 的ngComponentOutlet。

【讨论】:

  • 感谢 Theophilus 的反馈,不幸的是,当我使用上面描述的“[innerHTML]="view"” 时,我在视图而不是数据上得到 {{theme.Name}},所以我仍然需要假装我正在使用“替换”命令进行插值,而我更希望可观察对象像往常一样处理替换。因此,我不想看到 {{theme.Name}},而是希望看到“黄色主题”(或我放在配置文件中的任何内容)。
  • 检查 plnkr 链接,它会替换它,或者您正试图让 Angular 将加载的 innerHTML 内容按照ng-include 的工作方式工作?
  • 是的。这个想法是我有多个主题。我有一些在这些主题中常见的文件。所以我想在不加载通用主题的情况下加载组件,因为我想使用原始主题而不是更改它。
  • 我查看了 plunkr 代码,它仍然有 "this.view = content.replace("{{theme.Name}}", this.theme.name);"这是我要删除的代码行,但仍然让它看起来和你在 plunkr 中的一样
  • 换句话说,您的代码和我的代码都可以工作,但使用的是魔术字符串。我不希望代码中包含魔术字符串。这是一个大项目,所以如果我能让这一页正常工作,我可以重构整个解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-11
  • 1970-01-01
  • 2020-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多