相关疑难解决方法(0)

在RxJs 5中分享Angular Http网络调用结果的正确方法是什么?

通过使用Http,我们调用一个执行网络调用并返回http observable的方法:

getCustomer() {
    return this.http.get('/someUrl').map(res => res.json());
}
Run Code Online (Sandbox Code Playgroud)

如果我们采用这个可观察的并添加多个订阅者:

let network$ = getCustomer();

let subscriber1 = network$.subscribe(...);
let subscriber2 = network$.subscribe(...);
Run Code Online (Sandbox Code Playgroud)

我们想要做的是确保这不会导致多个网络请求.

这可能看起来像是一个不寻常的场景,但实际上很常见:例如,如果调用者订阅了observable以显示错误消息,并使用异步管道将其传递给模板,那么我们已经有两个订阅者.

在RxJs 5中这样做的正确方法是什么?

也就是说,这似乎工作正常:

getCustomer() {
    return this.http.get('/someUrl').map(res => res.json()).share();
}
Run Code Online (Sandbox Code Playgroud)

但这是在RxJs 5中这样做的惯用方式,还是我们应该做其他事情呢?

注意:根据Angular 5 new HttpClient,.map(res => res.json())所有示例中的部分现在都没用,因为现在默认采用JSON结果.

rxjs angular2-services rxjs5 angular

281
推荐指数
11
解决办法
8万
查看次数

委托:Angular中的EventEmitter或Observable

我试图在Angular中实现类似委托模式的东西.当用户点击a时nav-item,我想调用一个函数然后发出一个事件,而该事件又由一些其他组件监听事件来处理.

这是场景:我有一个Navigation组件:

import {Component, Output, EventEmitter} from 'angular2/core';

@Component({
    // other properties left out for brevity
    events : ['navchange'], 
    template:`
      <div class="nav-item" (click)="selectedNavItem(1)"></div>
    `
})

export class Navigation {

    @Output() navchange: EventEmitter<number> = new EventEmitter();

    selectedNavItem(item: number) {
        console.log('selected nav item ' + item);
        this.navchange.emit(item)
    }

}
Run Code Online (Sandbox Code Playgroud)

这是观察组件:

export class ObservingComponent {

  // How do I observe the event ? 
  // <----------Observe/Register Event ?-------->

  public selectedNavItem(item: number) {
    console.log('item index changed!');
  }

}
Run Code Online (Sandbox Code Playgroud)

关键问题是,如何让观察组件观察相关事件?

event-delegation observable observer-pattern eventemitter angular

231
推荐指数
2
解决办法
12万
查看次数

在Angular2服务中多次发出Http请求

我创建了一个发出简单GET请求的服务:

private accountObservable = null;

constructor(private _http: Http) {
}

getAccount () {
    // If we have account cached, use it instead
    if (this.accountObservable === null) {
        this.accountObservable = this._http.get('http://localhost/api/account')
            .map(res => <Account> res.json().data)
            .catch(this.handleError);
    }

    return this.accountObservable;
}
Run Code Online (Sandbox Code Playgroud)

我在我的bootstrap函数中添加了该服务以在全局范围内提供它(我希望为所有组件提供相同的实例):

provide(AccountService, { useClass: AccountService })
Run Code Online (Sandbox Code Playgroud)

问题是当我在不同的组件中调用此服务时,每次都会发出GET请求.因此,如果我将其添加到3个组件,即使我检查是否已存在可观察量,也会发出3个GET请求.

ngOnInit() {
  this._accountService.getAccount().subscribe(
    account => this.account = account,
    error =>  this.errorMessage = <any>error
  );
}
Run Code Online (Sandbox Code Playgroud)

如何防止多次发出GET请求?

http angular

13
推荐指数
1
解决办法
2万
查看次数

如何链接rxjs可观察

我来自Angular1,就像链接承诺一样,我希望有类似的行为.

我在某类中有一个方法: -

{.........
      doLogin (username, password) {
            .......
            .......
            return this.http.get(api).subscribe(
                    data => {.....}, //enters here
                    err => {.....}
        }
Run Code Online (Sandbox Code Playgroud)

然后我称这种方法: -

 someclass.doLogin(username, password).subscribe(
           data => { }, //Not getting called
            err => { }
 }
Run Code Online (Sandbox Code Playgroud)

正如我上面提到的对上述代码的评论,订阅不会在调用者类中被调用.

有关如何做到这一点的任何建议?

rxjs angular

7
推荐指数
1
解决办法
7079
查看次数

Angular2 等待 JSON 文件加载

目前我正在加载一个 JSON 文件,如下所示:

翻译服务.ts

@Injectable()
export class TranslationService {

    private _messages = [];

    constructor(private _http: Http) {
        var observable = this._http.get("/app/i18n/localizable.it.strings").map((res: Response) => res.json());
        observable.subscribe(res => {
            this._messages = res;
        });
    }

    getTranslationByKey(key: string, args?: any[]) {
        return this._messages[key];
    }
}
Run Code Online (Sandbox Code Playgroud)

localizable.it.strings

{
    "home.nav.calendar": "Calendar",
    ...
}
Run Code Online (Sandbox Code Playgroud)

TranslationService被注入我的HomeComponent但问题是当我尝试通过管道读取这些值时,它们仍然需要在页面呈现时加载。

翻译.pipe.ts

@Pipe({name: 'translate'})
export class TranslatePipe implements PipeTransform {

    constructor(private _translation: TranslationService) {}

    transform(value: string, args: string[]) : any {
        return this._translation.getTranslationByKey(value);
    }
}
Run Code Online (Sandbox Code Playgroud)

知道如何在加载任何页面之前从 JSON 文件加载所有值吗?

javascript json typescript angular

5
推荐指数
1
解决办法
2072
查看次数

在Angular 2 API驱动的树视图中防止重复的HTTP请求

我有一个Angular 2应用程序,它调用JSON API将数据加载到嵌套的HTML列表中(<ol>).本质上是动态生成的树视图.由于API中的数据集最终会变得非常大,当用户打开分支时,树会逐渐填充(用户打开分支,使用已打开的节点的id调用API,API返回JSON对于节点的直接子节点的馈送,Angular将返回的JSON绑定到一些新的HTML <li>元素,并且树展开以显示新的分支).

你可以在这个Plunkr中看到它的实际效果.它使用递归指令并且运行良好. 目前,因为我无法打开公共请求的实际API,它只是调用静态JSON提要,因此每个节点的返回数据只是重复,但希望你能得到这个想法.

我现在要克服的问题是在分支关闭然后重新打开时防止无关的HTTP调用.读完HTTP客户端文档后,我希望这就像修改订阅数据服务的方法一样简单,将方法链接.distinctUntilChanged()app/content-list.component.ts文件,如下所示:

getContentNodes() {
    this._contentService.getContentNodes(this._startNodeId)
        .distinctUntilChanged()
        .subscribe(
            contentNodes => this.contentNodes = contentNodes,
            error =>  this.errorMessage = <any>error
        );
}
Run Code Online (Sandbox Code Playgroud)

但是,当我打开浏览器网络检查器时,每次重新打开相同的树分支时,它仍然会调用API.

谁能建议如何解决这个问题?

非常感谢.

编辑:

我正试图在下面实施@Thierry Templier的答案; 缓存API返回的数据.所以内容服务现在是:

import {Injectable}                 from 'angular2/core';
import {Http, Response}             from 'angular2/http';
import {Headers, RequestOptions}    from 'angular2/http';
import {ContentNode}                from './content-node';
import {Observable}                 from 'rxjs/Observable';

@Injectable()
export class ContentService {
    constructor (private http: Http) {}

    private _contentNodesUrl = 'app/content.json'; …
Run Code Online (Sandbox Code Playgroud)

angular2-services angular

5
推荐指数
1
解决办法
9790
查看次数

Angular 2, Concurrency in a shared service http observable

I have a shared service (starting from this suggestion) that cache and returns some data after first http request:

export class SharedService {
  constructor(private http:Http) {
  }

  getData() {
    if (this.cachedData) {
      return Observable.of(this.cachedData);
    } else {
      return this.http.get(...)
            .map(res => res.json())
            .do((data) => {
              this.cachedData = data;
            });
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

My problem is that I have some directives and components inside the same template that are all initialized at the same time and each one call simultaneously (inside …

concurrency service caching angular

5
推荐指数
1
解决办法
1171
查看次数