2017-01-03 55 views
1

我有一个应用程序,使用单一类型的对象的交易。我使用服务管理对象的状态。在一个组件中,我显示该对象。从这里你可以点击字段在另一个组件中编辑它们。您也可以点击按钮将新项目添加到字段并删除项目。角2模板的更新,但破单击处理

大部分能正常工作,但有时它打破没有任何错误消息的时间。我点击删除或编辑按钮或字段,没有任何反应。点击处理程序已损坏(我已在控制台中检查过)。这通常发生在我添加或从数组中删除后。

,因为当我加我使用HTTP,以确保它被保存到数据库中,然后返回后,才观察到的新的液滴做一个元素,我让角更新显示,这是非常令人困惑。显示屏始终更新。然而,有时显示更新,但Augury没有意识到,这很奇怪。因此,我会添加一个提示,例如,提示将在数据库中可见,返回并更新视图,但Augury不会在组件中看到它。

它也不一致。有时候工作很好。

这里是从视图一些示例代码。

<h4>Hints (optional)</h4> 
<button class="btn btn-sm" [routerLink]="['/create/create5']">Add New</button> 
<div *ngIf="droplet.hints.length < 1">None</div> 
<div class="row" *ngFor="let hint of droplet.hints; let i=index"> 
    <div class="hint col-md-10" (click)="selectHint(i)"> 
    <span [innerHTML]="hint.content || empty"></span> 
    <span (click)="removeElement(i, 'hint')" class="pull-right glyphicon glyphicon-remove" aria-hidden="true"></span> 
    </div> 
</div> 

<h4>Tags 
    <div class="progress-marker" [class.complete]="droplet.tags.length > 0"></div> 
    <div class="progress-marker" [class.complete]="droplet.tags.length > 1"></div> 
    <div class="progress-marker" [class.complete]="droplet.tags.length > 2"></div> 
</h4> 
<button class="btn btn-sm" [routerLink]="['/create/create6']">Add New</button> 
<div *ngIf="droplet.tags.length < 1">None</div> 
<br> 
<button *ngFor="let tag of droplet.tags; let i=index" type="button" class="btn btn-default btn-sm" (click)="removeElement(i, 'tag')"> 
    <span class="glyphicon glyphicon-remove" aria-hidden="true"></span> {{ tag.tag }} 
</button> 

有几场这样的,但一般与* ngIf的那些是造成问题的人。正如我说,如果我添加或删除或编辑数组中它的作品的元素,模板更新,但往往没有在阵列后工作正常(虽然非阵列正常工作)。

相关组件的代码如下所示:

import { Component, OnInit } from '@angular/core'; 
import { Droplet } from '../droplet'; 
import { DropletService } from '../droplet.service'; 
import { Router } from '@angular/router'; 
import { Subscription } from 'rxjs/Rx'; 
import { HttpService } from '../http.service'; 

export class ShowDropletComponent implements OnInit { 
    droplet: Droplet; 

    constructor(
    private dropletService: DropletService, 
    private router: Router, 
    private httpService: HttpService 
) { } 

    ngOnInit() { 
    this.droplet = this.dropletService.getCurrentDroplet(); 
    this.dropletService.pushedDroplet.subscribe(
     droplet => this.droplet = droplet 
    ) 
    } 

    //using dummy to ensure element not updated unless returned from server 
    removeElement(index, element) { 
    console.log("remove clicked"); 
    let dummy = this.droplet; 
    if (element === "explanation") { 
     this.router.navigate(['create/create3']); 
     dummy.explanations.splice(index, 1); 
    } else if (element === "question") { 
     this.router.navigate(['create/create4']); 
     dummy.questions.splice(index, 1); 
    } else if (element === "hint") { 
     this.router.navigate(['create/create5']); 
     dummy.hints.splice(index, 1); 
    } else if (element === "tag") { 
     dummy.tags.splice(index, 1); 
    } 
    this.httpService.saveDroplet(dummy) 
     .subscribe(
     (droplet: Droplet) => { 
      this.dropletService.updateCurrentDroplet(droplet); 
     } 
    ); 
    } 

    editThis(field) { 
    if (field === "description") { 
     this.router.navigate(['create/create2']); 
    } else if (field === "name") { 
     this.router.navigate(['create/create1']); 
    } 
    } 

    selectExplanation(index) { 
    console.log("select exp clicked"); 
    this.router.navigate(['create/create3', index]); 
    } 

    selectQuestion(index) { 
    console.log("rselect q clicked"); 
    this.router.navigate(['create/create4', index]); 
    } 

    selectHint(index) { 
    console.log("select hint clicked"); 
    this.router.navigate(['create/create5', index]); 
    } 

} 

我的猜测是,它的东西做的* ngFor更新在视图中的数组,但无论是指数不正确更新或点击处理程序打破,但不仅仅是模板的特定部分。我很茫然。

回答

1

当在*ngFor指令操作的项目,它添加一个trackBy函数返回一个唯一索引是很重要的 - 所以删除/添加项目时,该指令可以跟踪他们财产。

假设你tag.tag是独一无二的,你可以写你的*ngFor这样,而不是:

<button *ngFor="let tag of droplet.tags; let i=index; trackBy: tag.tag" type="button"... 
+0

看来你现在需要使用一个函数,当你使用trackBy,我已经做了,返回每个项目的ID。但遗憾的是这并没有帮助。我遇到同样的问题。 – Finnjon

0

这个问题的解决很奇怪。我有左侧编辑窗体和右侧正在编辑或创建的液滴的并排组件。您可以点击右侧的按钮或字段,并在左侧显示相应的表单进行编辑。问题是,如果显示的液滴的字段在左侧的组件右下方延伸,则点击将失效,浏览器将简单地滚动到屏幕的顶部。我不知道为什么发生这种情况,但是在同一个视口内强制这一切解决了问题。