Angular 2:从服务更新组件视图

时间:2016-10-20 00:53:18

标签: angular

我有一个组件,显示从服务中检索的变种列表,如您所见。

export class SellingMenuVarietiesComponent implements OnInit {
    varieties: Variety[];

    constructor(public sellingMenuService: SellingMenuService) { }

    ngOnInit(): void {        
        this.getVarietyList();
    }
    // Get Variety List
    getVarietyList(): void {
        this.sellingMenuService.getVarieties().subscribe(res => {
            this.varieties = res;
        });
    }    
}

我有另一个组件可以删除变种,如下所示:

export class SellingVarietyEditComponent implements OnInit {
    constructor(private sellingMenuService: SellingMenuService) { }

    // Remove variety
    removeVariety(id: number) {        
        this.sellingMenuService.removeVariety(id).subscribe(res => {
            this.sellingMenuService.getVarieties();
        });        
    }
}

在此示例中,两个组件同时在页面上可见,因此当您删除各种组件时,我希望列表自动更新并反映出来。目前,该品种将成功从数据库中删除,但在我刷新页面之前将保留在列表中。请注意removeVariety()中的SellingVarietyEditComponent函数,我从我的服务中重新调用getVarieties()方法,试图让列表更新,但它不起作用。

我做错了什么?我怎样才能做到这一点?

以下是该服务的相关功能:

@Injectable()
export class SellingMenuService {
    // Get Variety List
    public getVarieties(): Observable<any> {
        return this.http.get(this.varietyList).map(response => {            
            return response.json();
        }, (error: any) => {
            console.log(error);
        });
    }
    // Remove Variety
    public removeVariety(varietyId: any): Observable<any> {
        return this.http.get(this.removeVarietyUrl + varietyId).map(response => {
            return response;
        }, (error: any) => {
            console.log(error);
        });
    }
}

编辑:

尝试使用EventEmitter解决方案:

SellingMenuService中,我添加了此代码(注意我将this.updateVarietyList.emit(null);添加到getVarieties()):

@Output() updateVarietyList: EventEmitter<any> = new EventEmitter();

// Get Variety List
public getVarieties(): Observable<any> {
    return this.http.get(this.varietyList).map(response => {            
        this.updateVarietyList.emit(null);
        return response.json();
    }, (error: any) => {
        console.log(error);
        // TODO: implement error handling here.
    });
}

SellingVarietyEditComponent中,我的删除按钮如下所示:

<a class="remove-button" (click)="removeVariety(varietyId)" (updateVarietyList)="onVarietyListUpdate($event)" >Remove</a> 

最后在SellingMenuVarietiesComponent我添加了这个:

onVarietyListUpdate() {
    console.log('test');
    this.getVarietyList();
}

但此代码不起作用。我没有收到任何错误,但onVarietyListUpdate()方法永远不会执行。我在正确的道路上吗?我怎样才能解决这个问题?我发现的例子令人困惑,我无法将它们应用到我的代码中。

2 个答案:

答案 0 :(得分:1)

我刚才意识到你有不同的组件。所以解决方案实际上会改变但是我仍然保留了旧的解决方案,如果您将来需要,可以更好地解决这些问题。

新解决方案

您可以在

中创建component-interactions.service.ts
updateVarieties = new Subject();
updateVarieties$ = this.updateVarieties.asObservable();
getVarieties(){
this.updateVarieties.next();
}

在这里,

export class SellingMenuVarietiesComponent implements OnInit {
    varieties: Variety[];

    constructor(private ciService:ComponentInteractionService, public sellingMenuService: SellingMenuService) { }

    ngOnInit(): void {        
        this.ciService.updateVarieties$.subscribe(()=> {
            this.getVarieyList();
      });
  this.getVarietyList();
    }
    // Get Variety List
    getVarietyList(): void {
        this.sellingMenuService.getVarieties().subscribe(res => {
            this.varieties = res;
        });
    }    
}

在编辑组件中,

export class SellingVarietyEditComponent implements OnInit {
    constructor(private ciService:ComponentInteractionService, private sellingMenuService: SellingMenuService) { }

    // Remove variety
    removeVariety(id: number) {        
        this.sellingMenuService.removeVariety(id).subscribe(res => {
            this.ciService.getVarieties();
        });        
    }
}

旧解决方案:如果单个组件手柄编辑和显示

您需要使用新数据更新UI。 一种方法是在删除变种后,使用后端的成功响应返回更新的变种。

所以,我点击了removeVariety API,用id执行删除操作,你在后端执行类似types.getAll()的操作,并在成功响应中发送更新的变量。然后你就做了

this.varieties = res;

这对前端来说很简单。

另一种方法是在点击删除API之前将id保存在变量中。 现在你有了你要删除的id,你点击了API,它成功了然后你做了

export class SellingVarietyEditComponent implements OnInit {
constructor(private sellingMenuService: SellingMenuService) { }

// Remove variety
removeVariety(id: number) {
    let deleteItemId = id; 

    this.sellingMenuService.removeVariety(id).subscribe(res => {
         if(res.status=="SUCCESS"){ /* check if it was successful.(Good practice to include that in API Response*/
         this.deleteItemById(deleteItemId);
       }
     });        
    }

deleteItemById(id:number){
this.varieties.forEach((value)=> {
  if(value.varietyId==id){
      let index = this.varieties.indexOf(value);
      if(index>-1){
         this.varieties.splice(index, 1);
      }
   }
 });
}

我认为再次调用getVarieties不是一个好主意。在你的代码中为什么它不起作用是因为它返回一个observable而你没有订阅它并更新品种数组。如果您仍想调用get API。你可以做到

 this.getVarietyList(); 

而不是

this.sellingService.getVarieties();

并在编辑组件中再次使用与其他组件相同的功能。

答案 1 :(得分:0)

您可以使用EventEmitter中的SellingMenuServicevariety被删除/更新时发出事件。在SellingMenuVarietiesComponent中收听此活动,并相应地更新您的数组