两个子组件之间的更改检测

时间:2019-03-29 15:39:04

标签: angular

我具有以下父组件:

export class CheckoutComponent implements OnInit {

    public customer: Customer;
    public items: Array<Item>;

    constructor(private sharingDataService: SharingDataService) { }

    ngOnInit(): void {
        this.sharingDataService.setCustomer(this.initializeCustomer());
        this.sharingDataService.setItems(this.initiatlizeItems());
        this.customer = this.sharingDataService.getCustomer();
        this.items = this.sharingDataService.getItems();
    }
    ......
}

使用以下html:

<div>
    <app-shipping-option></app-shipping-option>
    <app-review></app-review>
</div>

第一个孩子“应用程序运送选项”

export class ShippingOptionComponent implements OnInit {

    public options: Array<Option> = [];

    constructor(private sharingDataService: SharingDataService) { }

    ngOnInit(): void {
        this.initializeOptions();
    }

    private initializeOptions(): void {
        let option1: Option = {
            name: 'Free',
            price: 0
        };
        let option2: Option = {
            name: 'Paid',
            price: 15
        };
        this.options.push(option1, option2);
    }

    private createCustomerForm(): void {
        this.shippingOptionForm = this.formBuilder.group({
            option: [this.options[0], Validators.required]
        });
    }

    chooseOption(option): void {
        this.sharingDataService.setShippingOption(option);
    }
}

这里是第二个孩子“评论”

export class ReviewComponent implements OnInit {

    constructor(private sharingDataService: SharingDataService) { }

    ngOnInit(): void {
        console.log(this.sharingDataService.getShippingOption())
    }
}

我想检测第二个孩子中的更改,因此当我更改第一个孩子上的选项时,第二个孩子应在控制台上打印此选项。但是上面的代码会在init上打印第一个提供的选项。这些cour子项会显示在同一页面上,而ngOnInit会在页面加载时被调用。

这是用于在组件之间共享数据的服务:

@Injectable()
export class SharingDataService {

    private data: InputDetails = new InputDetails();

    constructor() { }

    setShippingOption(shippingOption): void {
        this.data.shippingOption = shippingOption;
    }

    getShippingOption(): { name: string, price: number } {
        return this.data.shippingOption;
    }
}

2 个答案:

答案 0 :(得分:1)

    You can use Subject type of an observable to achieve this. 

    Here is how to use it:

    In Service File: Create the Subject

    import { Subject } from 'rxjs/internal/Subject';

    export class SharingDataService {
      public abcObservable = new Subject<object>();
    }

    In Child1: import the Service within the constructor and use the .next() to emit values whenever you see a change in options on this child

import { SharingDataService } from ....;

export class ShippingOptionComponent implements OnInit {

    public options: Array<Option> = [];

    constructor(private sharingDataService: SharingDataService) { }

    chooseOption(option): void {
        this.sharingDataService.abcObservable.next(option);
    }

}

In Child2: Subscribe to this Subject

export class ReviewComponent implements OnInit {

    constructor(private sharingDataService: SharingDataService) { }

    ngOnInit(): void {

        this.sharinDataService.abcObservable.subscribe(

      (data) =>  console.log("Call your next methods from here!"),
      (error) => console.log("When there is an error in the observable, it comes here", error),
      () => console.log("If the subject completes sending all values, it comes in here")
    );
    }
}

More details aout how to share data between different components can be read here: https://angularfirebase.com/lessons/sharing-data-between-angular-components-four-methods/

答案 1 :(得分:0)

您可以使用rxjs中的Subject Class,这是如何进行某种通知的example