【问题标题】:How to set a variable in another angular 2 component如何在另一个角度 2 组件中设置变量
【发布时间】:2017-07-28 18:38:14
【问题描述】:

我正在构建一个 Angular 4 应用程序,我有 2 个单独的页面,一个详细信息页面和一个编辑页面,每个页面都有自己的组件。

当用户在编辑页面上编辑模型时,我将他们重定向回详细信息页面,如下所示:

// This is within my RetailerEditComponent
save(): void {
    this.retailerService.updateRetailer(this.retailer)
        .then(() => this.router.navigate(['/admin/retailer']));
}

在管理/零售商页面中,我有一个如下所示的 RetailerDetailComponent:

export class RetailerDetailComponent {
    retailer: Retailer;

    public hasBeenUpdated: boolean = false;

    constructor(
        private retailerService: RetailerService,
    ) {
        console.log("in RetailerDetailComponent");
    } 
}

如何从我的其他页面将 bool hasBeenUpdated 设置为 true?

更新:

我喜欢 EventEmitter 的想法,但遇到了问题。

我的零售商服务:

export class RetailerService {
    public OnRetailerUpdated = new EventEmitter();;

    updateRetailer(retailer: Retailer): Promise<Retailer> {
        this.OnRetailerUpdated.next(true);
        return new Promise((resolve, reject) => {
            apigClient.retailerVPut({}, retailer, {})
                .then(function (result) {                            
                      resolve(result.data[0])
                 }).catch(function (result) {
                      reject(result)
                 });
                }
            })

        });
    }

}

在我的 RetailerDetailComponent 中:

导出类 RetailerDetailComponent 实现 LoggedInCallback { 零售商:零售商;

public showError: boolean;

constructor(
    private retailerService: RetailerService) {

}
ngOnInit(): void {
    this.retailerService 
        .OnRetailerUpdated 
        .subscribe(value => {  
            this.showError = true;
            console.log('Event thingy worked')
        });
}

但控制台消息不显示

【问题讨论】:

  • 请查看更新,偶数发射器中缺少布尔值:new EventEmitter&lt; boolean &gt;();

标签: angular


【解决方案1】:

你有几个选择:

第一个是在您的服务中创建一个零售商地图,指示哪些零售商已更新并在您调用 updateRetailer 方法时设置值。

public retailersUpdateStates: { [id: string]: Retailer } = {};

以及检查状态的方法:

public hasBeenUpdated(retailer: Retailer) {
    return !!this.retailersUpdateStates[retailer.id]
}

方法被调用时:

retailersUpdateStates[retailer.id] = true; 

在你的组件中:

public get hasBeenUpdated() {
    return this.retailersService.hasBeenUpdated(this.retailer);
}

第二个方法是将hasBeendUpdated 属性添加到Retailer 模型并相应地更新它。在您的组件模板中,您可以这样做:

{{ retailer?.hasBeenUpdated }}

第三个是使用路由器参数,这是已更新的零售商 ID。 (但这似乎没那么花哨)。

还有更多方法,例如使用ngrx 进行状态管理。正如@faisal 的回答中所描述的,有了这个“单一事实来源”,跨组件共享状态或使用 rxjs 主题来管理零售商状态将是一件轻而易举的事。

【讨论】:

  • 这是一个非常合理的做法。或者,您可以通过路由参数传递该值:angular.io/guide/router#route-definition-with-a-parameter
  • 是的,这会将状态绑定到 url,这在某些情况下可能很好,但可能会产生一些不需要的 ui 效果,因为用户总是可以访问该 url,它会告诉他组件已更新,即使尚未更新。
【解决方案2】:

使用例如RetailerService 在组件之间共享公共变量。

【讨论】:

    【解决方案3】:

    最好的方法是将订阅与 EventEmitter 一起使用。下面的例子:

    1. 您可以在零售商服务中定义事件发射器:

    public OnRetailerUpdated = new EventEmitter();

    1. 然后,在您的“updateRetailer”方法中,添加以下行:

    this.OnRetailerUpdated.next(true);

    1. 在您的 RetailerDetailComponent 中订阅此活动:

    this.retailerService .OnRetailerUpdated . 订阅(值 => { // 在此处执行适当的操作 });

    private subscription;
    
    ngOnInit() {  
        this.subscription = this.retailerService.OnRetailerUpdated
                                .subscribe(value => { 
                                  // Perform the appropriate action here 
        }); 
    };
    
    ngOnDestroy() { 
        this.subscription.unsubscribe(); 
    };
    

    【讨论】:

    • @RobbieMills 你可以把它放在 ngOnInit() 中,记得在视图被销毁后取消订阅以避免任何内存泄漏或多次订阅。请参阅我的更新答案。
    猜你喜欢
    • 2017-05-28
    • 2023-01-05
    • 2016-04-27
    • 2018-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-07
    相关资源
    最近更新 更多