【问题标题】:Angular2: watching changes in a subset of dataAngular2:观察数据子集的变化
【发布时间】:2015-11-07 17:45:13
【问题描述】:

(我的问题与this one 有关,但它处理的是解析一次的数据,而我需要重复解析。)

我下载了 400 个项目,并将其过滤为默认的 20 个。用户可以更改过滤器,从而向他们显示 20 个结果。我应该使用服务来存储数据并应用过滤器,还是应该只在父组件中处理它?如果是前者(感觉更好的做法),我需要一些帮助来连接它。

我有以下服务定义,它将下载数据:

@Injectable()
export class RestosSvc {
    http: Http;
    data: {
        restos : Array<Resto>;
        recommendations: Array<Resto>;
    };

    constructor(http:Http) {
        console.log('RestosSvc constructor');
        ...

简而言之,restos 在引导时成为来自服务器的 400 强列表,recommendations 是其中的一小部分。然后,根据用户输入,推荐的选择会发生变化。

我的计划是使用这个html(组件home,被顶级app调用)

<h1>Home</h1>
<filters></filters>

<map [recommendations]="recommendations"></map>

<list [recommendations]="recommendations"></list>

然后我需要找到一种方法来在下载数据后刷新recommendations,并在随后由于使用的过滤器的变化而发生变化。

问题:

  • 应该Filters 直接与服务对话,还是由其父级提供一个事件处理程序,由其自身与服务对话?
  • 如何设置服务,以便在更新 recommendations 后,将此信息提供给。

在我的 Angular 1 代码中,我让过滤器将新的过滤器信息发送到服务,该服务计算要显示的内容,然后 $broadcast 一个事件,以便组件可以自行刷新:

      this.data.recommendations = ...

      // this.$rootScope.$broadcast('recommendations');

我的 home 组件目前仅在引导时获得空推荐(在下载 restos 并应用默认过滤器之前)

export class HomeCmp {
  recommendations : Array<Resto>;

  constructor(restos: RestosSvc) {
    // ObservableWrapper.subscribe(  
    //   restos.data.recommendations, 
    //   recs => this.recommendations = recs
    // );
    this.recommendations = restos.data.recommendations;
  }
}

【问题讨论】:

  • 这样的plnkr是你想要的吗?
  • @EricMartinez 就最终结果而言是的,但是您已将数据处理放在父组件中,据我所知,该服务实际上并未被使用。在实践中,我的应用程序并没有那么复杂,所以我也许也可以这样做,但感觉不是“最佳实践”,也不是我认为应该采用的方式。我希望将过滤器中的事件传递给服务,重新计算推荐,然后将其传递给父组件以馈入地图和列表
  • 我也很惊讶你让 Angular2、TS 和 SystemJS 看起来如此简单——我最终自己做了并开始使用种子,但是你使用的是你不理解的代码。我也可能以您的框架为基础!
  • 如果您可以为一些 Plunker 提供简化的示例(我发现从当前的代码示例中很难理解),那么理解问题/疑问会容易得多。 10 倍!
  • 好的,明天我可能会使用@EricMartinez 的模板,因为我现在太累了

标签: observable angular


【解决方案1】:

我不确定我是否理解你的问题,但我想答案是 Angular 2 有一个内置的 observable - http 将返回一个 observable,而不是一个承诺!查看this 帖子了解更多详情。基本思想是你现在可以做这样的事情(参考来自帖子):

getRandomQuote() {
  this.http.get('http://localhost:3001/api/random-quote')
    .map(res => res.text())
    .subscribe(
      data => this.randomQuote = data,
      err => this.logError(err),
      () => console.log('Random Quote Complete')
    );
}

响应式编程是在 Angular 2 中构建的,因此您不必为了使用它而做一些特别的事情...

希望这回答了您的问题。如果不是,请添加更多解释。

编辑

作为对您上次编辑的回应,我想最好使用单向树数据流(类似于 React 的方法)。这意味着数据/状态应该是不可变的,并且不应被不拥有它的组件更改。

我认为数据应该来自父组件,并且在用户交互时,过滤器组件应该向父组件触发一个事件,该事件将通知子组件有关更改(这是通过Input数据,使用@ 987654324@ 语法)。

希望我能正确理解您的问题!

【讨论】:

  • 是的,我可以看到如何在加载时获取数据,但是如何处理导致对完整数据进行不同过滤的用户事件,这需要重新渲染数据
  • @SimonH:请看我最后的编辑。希望它能回答你的一些问题。
【解决方案2】:

好的,所以我通过改编@EricMartinez plnkr 解决了这个问题。 This one 是基于他的,但将更多的数据处理委托给服务。

export class Hello {
  original: [];
  recommendations: [];

  constructor(public svc: RestosSvc) {
  }

  downloadData() {

    // Data coming from the server via service
    this.svc.http
      .subscribe((data) => {
        this.original = data;
        this.recommendations = this.original;
      });
  }

  handleFilterChange(count) {
    // Filter 
    console.log(count);
    this.recommendations = this.original.slice(0, count);
  }
}

【讨论】:

    猜你喜欢
    • 2019-03-01
    • 2012-02-22
    • 2017-11-05
    • 2020-09-13
    • 2016-09-25
    • 2017-05-07
    • 1970-01-01
    • 2016-09-29
    • 2020-11-07
    相关资源
    最近更新 更多