处理角度异步管道更改检测

问题描述 投票:-1回答:1

我有一个带有多个字段和图像框的表单,用于通过safeLink和Async管道显示图像。

问题是,在首次生成组件时会填充字段,但是一旦异步实现image src属性请求,我们就只能看到该图像,而看不到其他任何内容。此外,字段上的ngModel属性仍保留值;在视觉上,该字段为空。

据我了解,异步管道标记了可观察对象发出新值时要检查的组件更改。

图像分辨率代码:

<div class="card" style="width: 18rem;">
    <img class="card-img-top" [src]="getImgLink(answer) | secure | async" alt="Card image cap">
</div>

这是我对可观察到的安全管道的代码:

@Pipe({
  name: 'secure'
})
export class SecureURL implements PipeTransform {

  constructor(private http: HttpClient, private sanitizer: DomSanitizer) { }

  transform(url): Observable<SafeUrl> {
    return this.http
      .get(url, { responseType: 'blob' })
      .pipe(map(val => this.sanitizer.bypassSecurityTrustUrl(URL.createObjectURL(val))));
  }

}

这是我主要组件的代码:

@Component({
    moduleId: module.id,
    selector: 'questionnaire-form',
    template: /* See template below */
})
export class QuestionnaireComponent implements OnInit, OnChanges {

    @Input('respondent') respondent: Respondent;
    @Input() questionnaire: Questionnaire;
    public myForm= new FormGroup({});

    constructor(private _projectService: ProjectService, private formBuilder: FormBuilder,@Inject(DOCUMENT) private document: Document) {
      console.log('constructing questionnaire component');
    }

    ngOnInit() {
      console.log('initializing questionnaire component');
    }

    toGroup():boolean {
        const group: any = [];
        for (const question of this.questionnaire.questions) {
            if (question.validator != null) {
                const validtxt = question.validator;
                switch (validtxt) {
                    case 'alpha':
                        group[question.no] = new FormControl('', Validators.required);
                        break;
                    case 'email':
                        group[question.no] = new FormControl('', [Validators.required, ValidationService.emailValidator]);
                        break;
                    case 'phone':
                        group[question.no] = new FormControl('', [Validators.required, ValidationService.phoneValidator]);
                        break;
                    case 'numeric':
                        group[question.no] = new FormControl('');
                        break;
                    case 'canadaCode':
                        group[question.no] = new FormControl('');
                        break;
                    case 'usaCode':
                        group[question.no] = new FormControl('');
                        break;
                }
            } else {
                group[question.no] = new FormControl('');
            }

        }
       this.myForm = this.formBuilder.group(group);
        return true;
    }

    private getImgLink(answer:string):string {
      console.log(answer);
      if(answer.includes('jpg') || answer.includes('png')) {
        return 'http://'+this.document.location.hostname+':8080/'+answer;
      }

      return 'http://'+this.document.location.hostname+':8080/'+'emailTemplates/samplePlaceholder.jpg';
    }

    private getRespondentAnswer(respondent:Respondent,qNo:number):string {

      return respondent.responses.get(qNo).answer;
    }

  ngOnChanges(changes: SimpleChanges): void {

      console.log('Async triggered change checked');
  }
}

这里是组件的模板:

<form *ngIf="questionnaire!=null && toGroup()" [formGroup]="myForm" novalidate>
    <div *ngFor="let question of this.questionnaire.questions" class="form-group">
         <div *ngIf="question.toSave && respondent.responses.get(question.no)!=null">
                <label>{{question.no}}) {{question.texts.get(respondent.language)}}</label>
                <div [ngSwitch]="question.type">
                    <ng-container *ngSwitchCase="'combo'">
                    <select formControlName="{{question.no}}" class="form-control" [(ngModel)]="respondent.responses.get(question.no).answer">
                        <option *ngFor="let choice of question.choices[0].texts.get(respondent.language)" [value]="choice" [selected]="choice === respondent.responses.get(question.no).answer">{{choice}}</option>
                    </select>
                    </ng-container>
                    <ng-container *ngSwitchCase="'radio'">
                        <div *ngFor="let choice of question.choices" class="radio">
                            <label>
                            <input type="radio"  [(ngModel)]="respondent.responses.get(question.no).answer"  formControlName = "{{question.no}}" [value]="choice.texts[respondent.language]">
                                {{choice.texts[respondent.language]}}
                        </label>
                        </div>
                    </ng-container>
                    <ng-container *ngSwitchCase="'check'">
                        <div *ngFor="let choice of question.choices" class="check">
                            <label>
                            <input type="checkbox" [(ngModel)]="respondent.responses.get(question.no).answer" formControlName="{{question.no}}">
                                {{choice.texts[respondent.language]}}
                            </label>
                        </div>
                    </ng-container>

                    <ng-container *ngSwitchCase="'picture'">
                        <input  formControlName="{{question.no}}" type="text" class="form-control" [(ngModel)]="respondent.responses.get(question.no).answer" readonly />
            <br>
            <imageViewer [answer]="respondent.responses.get(question.no).answer"></imageViewer>
          </ng-container>

          <ng-container *ngSwitchCase="'vimeo'">
            <input  formControlName="{{question.no}}" type="text" class="form-control" [(ngModel)]="respondent.responses.get(question.no).answer" readonly /> <!--question.choices[0].answer-->
            <br/>
            <div class="embed-responsive embed-responsive-4by3">
              <iframe class="embed-responsive-item" src="https://player.vimeo.com/video/{{respondent.responses.get(question.no).answer}}"></iframe>
            </div>
          </ng-container>

                    <ng-container *ngSwitchCase="'photo_bundle'">
                        <input  formControlName="{{question.no}}" type="text" class="form-control" [(ngModel)]="respondent.responses.get(question.no).answer" readonly />
                    </ng-container>

                    <ng-container *ngSwitchDefault>
                        <ng-container *ngIf="question.validator == null" >
                            <input  *ngIf="question.validator == null" formControlName="{{question.no}}" type="text" class="form-control"  [(ngModel)]="respondent.responses.get(question.no).answer"/>
                      </ng-container>
                        <ng-container *ngIf="question.validator != null">
                            <ng-container [ngSwitch]="question.validator">
                                <ng-container *ngSwitchCase="'alpha'">
                                <input  formControlName="{{question.no}}" type="text" class="form-control" [(ngModel)]="respondent.responses.get(question.no).answer">
                                <control-message [control]="myForm.controls[question.no]"></control-message>
                                </ng-container>
                                <ng-container *ngSwitchCase="'email'">
                                    <input formControlName="{{question.no}}" type="text" class="form-control" [(ngModel)]="respondent.responses.get(question.no).answer" />
                                    <control-message [control]="myForm.controls[question.no]"></control-message>
                                </ng-container>
                                <ng-container *ngSwitchCase="'phone'">
                                    <input formControlName="{{question.no}}" type="text" class="form-control" [(ngModel)]="respondent.responses.get(question.no).answer" />
                                    <control-message [control]="myForm.controls[question.no]"></control-message>
                                </ng-container>
                                <ng-container *ngSwitchCase="'numeric'">
                                    <input formControlName="{{question.no}}" type="text" class="form-control" [(ngModel)]="respondent.responses.get(question.no).answer" />
                                </ng-container>
                                <ng-container *ngSwitchCase="'canadaCode'">
                                    <input formControlName="{{question.no}}" type="text" class="form-control" [(ngModel)]="respondent.responses.get(question.no).answer" />
                                </ng-container>
                                <ng-container *ngSwitchCase="'usaCode'">
                                    <input formControlName="{{question.no}}" type="text" class="form-control" [(ngModel)]="respondent.responses.get(question.no).answer" />
                                </ng-container>
                            </ng-container>
                        </ng-container>
                    </ng-container>
                </div>
         </div>
    </div>
</form>

enter image description here

angular asynchronous pipe
1个回答
0
投票

我已经找到了解决方案,它并不是我最初想要的,但是它解决了我的问题,我可以继续进行下去。解决方案是将以下属性简单地添加到输入中:(ngModelChange)和[value]

另一种解决方案是异步填充输入。

© www.soinside.com 2019 - 2024. All rights reserved.