【问题标题】:Angular2: convert array to ObservableAngular2:将数组转换为 Observable
【发布时间】:2016-06-02 08:04:18
【问题描述】:

我有一个通过 http 从服务中获取数据的组件,问题是我不想每次显示这个组件时都访问 API 后端。我希望我的服务检查数据是否在内存中,如果是,则返回一个带有内存中数组的 observable,如果不是,则发出 http 请求。

我的组件

import {Component, OnInit } from 'angular2/core';
import {Router} from 'angular2/router';

import {Contact} from './contact';
import {ContactService} from './contact.service';

@Component({
  selector: 'contacts',
  templateUrl: 'app/contacts/contacts.component.html'
})
export class ContactsComponent implements OnInit {

  contacts: Contact[];
  errorMessage: string;

  constructor(
    private router: Router,
    private contactService: ContactService) { }

  ngOnInit() {
    this.getContacts();
  }

  getContacts() {
    this.contactService.getContacts()
                       .subscribe(
                         contacts => this.contacts = contacts,
                         error =>  this.errorMessage = <any>error
                       );
  }
}

我的服务

import {Injectable} from 'angular2/core';
import {Http, Response, Headers, RequestOptions} from 'angular2/http';
import {Contact} from './contact';
import {Observable} from 'rxjs/Observable';

@Injectable()
export class ContactService {

  private contacts: Array<Contact> = null;

  constructor (private http: Http) {

  }

  getContacts() {
    // Check first if contacts == null
    // if not, return Observable(this.contacts)? <-- How to?

    return this.http.get(url)
                    .map(res => <Contact[]> res.json())
                    .do(contacts => {
                      this.contacts = contacts;
                      console.log(contacts);
                    }) // eyeball results in the console
                    .catch(this.handleError);
  }


  private handleError (error: Response) {
    // in a real world app, we may send the server to some remote logging infrastructure
    // instead of just logging it to the console
    console.error(error);
    return Observable.throw(error.json().error || 'Server error');
  }
}

【问题讨论】:

    标签: http angular rxjs


    【解决方案1】:

    你也可以使用Observable.of(resultArray);

    来自import { Observable } from 'rxjs;'

    【讨论】:

      【解决方案2】:

      在 angular7 中放置of() 就足够了。无论你放在里面 of() 将更改为可观察的。在这里,this.contacts 被转换 可以观察到。

      import { of } from 'rxjs'; 
      
      getContacts() {
      
          if(this.contacts != null) 
          {
              return of(this.contacts);
          } 
      }
      

      【讨论】:

        【解决方案3】:
        import { of } from 'rxjs';
        
        
        return of(this.contacts);
        

        【讨论】:

          【解决方案4】:

          像我这样的人想要的不同,从string[]变成Observable&lt;string&gt;

          这是一个涉及转换的示例:

          import { from } from 'rxjs/observable/from';
          import 'rxjs/add/operator/map';
          import 'rxjs/add/operator/toArray';
          
          const ids = ['x12', 'y81'];
          let userUrls: string[];
          
          from(ids) // Converting string[] into Observable<string>
            .map(id => 'http://localhost:8080/users/' + id)
            .toArray()
            .subscribe(urls => userUrls = urls);
          

          希望它能帮助其他人。

          【讨论】:

            【解决方案5】:

            这里的快速解决方案:

            getSomething():Observable<Object[]>{
                    return new Observable(observable => {
                        this.http.get('example.com').subscribe(results => {
                            observable.next(results.json());
                            observable.complete();
                        });
                    });
                }
            

            【讨论】:

              【解决方案6】:

              这可能会非常晚,但我一直在大量使用 sessionStorage 来处理我的一些工作。如果您因为人们四处走动而丢失状态,您仍然拥有您的数据。

               getSubjects(): Observable<Subject[]> {
                 
                  let SubjectsString = sessionStorage.getItem("Subjects")
              
                  if (SubjectsString) {
                    let subjects: Subject[] = JSON.parse(SubjectsString);
                    console.log("GETTING DATA FROM SESSION STORAGE")
                    return Observable.of(subjects);
                    
                  } else {
                    let url = `${this.apiHost}/api/subject`;
                    return this.http.get(url)
                      .map(res =>{          
                  
                        sessionStorage.setItem("Subjects",JSON.stringify(res.json()));           
                        return res.json();
                      })
                    
                    
                  }
              
                     
                }

              在这个例子中,我有一个 Subject 的类和一个 apiHost 的定义,但其余的都很简单。您调用该服务以获得可观察的。您的组件不知道数据在哪里,也不在乎。该服务检查本地存储,如果有,则将其转换为可观察对象并返回,如果没有,则获取它,然后将其保存到本地存储,然后返回。

              就我而言,我有一些包含数百页的大型应用程序。用户可能会从一个不错的新 Angular4 页面跳到经典的 ASP 时代,然后多次返回。将所有菜单项甚至搜索结果都保存在会话存储中是一种救命稻草。

              【讨论】:

                【解决方案7】:

                你就在那儿。如果内存中已有数据,可以使用 of observable(相当于 RxJS 4 中的 return/just)。

                getContacts() {
                
                    if(this.contacts != null) 
                    {
                        return Observable.of(this.contacts);
                    } 
                    else 
                    {
                        return this.http.get(url)
                            .map(res => <Contact[]> res.json())
                            .do(contacts => this.contacts = contacts)
                            .catch(this.handleError);
                    }
                }
                

                【讨论】:

                • 这可能是一个愚蠢的问题,但你不能只缓存 observable 本身并调用 .next() 而不是缓存状态并在每次调用时重新创建 observable 吗?
                • 好点,我试试。虽然当我想迭代数组以通过特定键返回单个联系人时,这不是最好的
                • 导入 'rxjs/add/observable/of';
                • @Eric Martinez,感谢您的回答。你从哪里得到的。我从 'rxjs' 导入了它,但它不在 Observable 中。
                猜你喜欢
                • 1970-01-01
                • 2023-03-16
                • 2014-10-24
                • 2020-12-01
                • 2017-09-24
                • 2017-07-30
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多