首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >父/子组件通信角2

父/子组件通信角2
EN

Stack Overflow用户
提问于 2017-11-17 14:25:21
回答 1查看 180关注 0票数 2

我未能在child_1组件中实现操作按钮,但事件处理程序位于子组件child_2中,如下代码所示:

app.component.html (父Html)

代码语言:javascript
复制
<div style="text-align:center">
  <h1>
    Welcome to {{title}}!
  </h1>
  <app-navigation></app-navigation> <!-- Child1-->
</div>

app.component.html (父组件)

代码语言:javascript
复制
import { Component } from '@angular/core';
import { ProductService } from './productservice';
import {Product} from './product';

@Component({
      selector: 'app-root',
      templateUrl: './app.component.html',
      styleUrls: ['./app.component.css'],
    })
    export class AppComponent {
      title = 'MobileShirtShoeApp';
    }

app.module.ts (主模块)

代码语言:javascript
复制
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpModule } from '@angular/http';
import { Product } from './product';
import { ProductService } from './productservice';
import { AppComponent } from './app.component';
import { NavigationComponent } from './navigation/navigation.component';
import { DataTemplateComponent } from './data-template/data-template.component';

@NgModule({
  declarations: [AppComponent,NavigationComponent,DataTemplateComponent],
  imports: [BrowserModule,HttpModule],
  providers: [ProductService],
  bootstrap: [AppComponent]
})

export class AppModule { }

navigation.component.html (儿童1 HTML)

代码语言:javascript
复制
<fieldset>
  <legend>Navigate</legend>
  <div>
     <button  (click)="loadMobiles()">Mobiles</button> <!--Child_1 Action-->
  </div>
  <app-data-template></app-data-template>
</fieldset>

navigation.component.ts (儿童1 Component.ts)

代码语言:javascript
复制
import { Component, OnInit } from '@angular/core';
import { ProductService } from '../productservice';
import {Product} from '../product';
import {DataTemplateComponent} from '../data-template/data-template.component';


@Component({
  selector: 'app-navigation',
  templateUrl: './navigation.component.html',
  styleUrls: ['./navigation.component.css']
})
export class NavigationComponent implements OnInit {
  error: string;
  productArray: Product[];

  constructor(private myService: ProductService){
    this.myService = myService;
  }

  dataTemplateComponent: DataTemplateComponent = new DataTemplateComponent(this.myService);

  ngOnInit() {
  }

  loadMobiles() {
   return this.dataTemplateComponent.loadMobiles();
  }
}

数据-template.Component.html(子2 HTML) (不显示数据)

代码语言:javascript
复制
<fieldset>
    <legend>Requested Data</legend>
    Welcome
    <div>
      <ul>
            <li *ngFor="let product of productArray">
                {{product.id}} {{product.name}} {{product.price}}
                <img src="{{product.url}}">
            </li>
        </ul>
    </div>
</fieldset>

数据-Template.Component.ts(子2组件)(包含产品服务调用代码)

代码语言:javascript
复制
import { Component} from '@angular/core';
import {Product} from '../product';
import {ProductService} from '../productservice';

@Component({
  selector: 'app-data-template',
  templateUrl: './data-template.component.html',
  styleUrls: ['./data-template.component.css']
})

export class DataTemplateComponent  {
  error: string;
  productArray: Product[];
  constructor(private productService: ProductService) {
    this.productService = productService;
  }

  loadMobiles(){
    let promise  = this.productService.fetchMobiles();
    promise.then(productArr => {
        return this.productArray = productArr;
      }).catch((err) => {
       this.error = err;
      });
  }
}

ProductService.ts

代码语言:javascript
复制
import 'rxjs/add/operator/toPromise';
import {Http, HttpModule} from '@angular/http';
import {Injectable} from '@angular/core';
import {Product} from './product';


@Injectable()
export class ProductService{
  http: Http;
  constructor(http: Http){
  this.http = http;
  console.log(http);
 }

fetchMobiles(): Promise<Product[]>{
  let url = "https://raw.githubusercontent.com/xxxxx/Other/master/JsonData/MobileData.json";
  return this.http.get(url).toPromise().then((response) => {
        return response.json().mobiles as Product[];
    }).catch(this.handleError);
}

private handleError(error: any): Promise<any> {
  console.error('An error occurred', error);
  return Promise.reject(error.message || error);
}
}

如果密码打扰了你,很抱歉。因此,基本上,当在child_2.html服务中所做的操作工作良好并命名为ProductService时,我无法在child_1.html.The中显示服务数据,该操作使用Product.ts作为对象来获取JSON格式的数据。任何帮助都是值得感激的。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-11-17 14:59:30

这不起作用,因为在应用导航中实例化的DataTemplateComponent与页面上的DataTemplateComponent不一样。这是一个全新的,您实例化的,它根本不绑定到页面。您想要实现的是组件通信。具体而言,父/子组件通信。有许多方法可以做到这一点,最干净和最灵活/可扩展的方法是使用共享服务模式。基本上,您声明的服务中包含一个可观察到的服务,您将其注入到两个服务中,其中一个服务更新可观测的服务,而另一个服务则订阅该服务,如下所示:

代码语言:javascript
复制
@Inject()
export class MyComponentCommunicationService {
    private commSubject: Subject<any> = new Subject();
    comm$: Observable<any> = this.commSubject.asObservable();
    notify() {
        this.commSubject.next();
    }
}

然后,根据应用程序导航中的需求,在应用程序模块或可能的父组件上提供此服务:

代码语言:javascript
复制
constructor(private commService: MyComponentCommunicationService) {}
loadMobiles() {
   this.commservice.notify();
}

在数据模板中:

代码语言:javascript
复制
constructor(private commService: MyComponentCommunicationService, private productService: ProductService) {}
ngOnInit() {
    this.commSub = this.commService.comm$.subscribe(e => this.loadMobiles());
}
ngOnDestroy() { this.commSub.unsubscribe(); } // always clean subscriptions

这可能有点不必要,因为您已经在那里获得了产品服务。您可能只需将load逻辑移到产品服务中,就可以触发可观察到的数据模板服务被订阅的情况,并让nav组件调用产品服务上的,但这只是为了说明这个概念。

我可能会这样做:

代码语言:javascript
复制
@Inject()
export class ProductService {
    private productSubject: Subject<Product[]> = new Subject<Product[]>();
    products$: Observable<Product[]> = this.productSubject.asObservable();
    loadMobiles() {
        this.fetchMobiles().then(productArr => {
            this.productSubject.next(productArr);
          }).catch((err) => {
            this.productSubject.error(err);
          });
    }
}

然后nav组件:

代码语言:javascript
复制
loadMobiles() {
   this.myService.loadMobiles();
}

然后是数据模板:

代码语言:javascript
复制
ngOnInit() {
    this.productSub = this.productService.products$.subscribe(
        products => this.productArray = products,
        err => this.error = err
    );
}
ngOnDestroy() { this.productSub.unsubscribe(); } // always clean subscriptions
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47352880

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档