问题
In the following pics, I visit a component, which on selecting a value from a drop down shows some values. If now, i click on home page and then revisit the component, then i still see the old values. Why is the component retaining old values?
on start
after selecting from drop box, the values gets populated
now visit home page
on revisiting, still seeing old values
The html of the component is
<div id="practice-questions-list-top-level-div">
<div id="practice-questions-tags-form-container" > <!-- this form takes 1st row -->
<form id="new-question-form" class="practice-question-form form-inline" [formGroup]="languageSelectorForm" (ngSubmit)="getQuestionsForSelectedLanguage()" novalidate>
<!-- label and small in same line. select in a new line, thus enclosed select in a div-->
<div class="form-group">
<label for="language-selector" class="control-label ">Select Language </label>
<div>
<!-- this select is binded to tags form control in the .ts file
Depending on whether this field has errors or not, Bootstrap css classes will be added to this field for visual representation
Specifically, is-valid and is-invalid will be added to a FormControl
-->
<select id="language-selector" class="selectpicker" formControlName="tags" [ngClass]="validateField(languageSelectorForm,'tags')" >
<!-- will [value] work [value]="tag.course+"-"+tag.subject+"-"+tag.topic" -->
<option *ngIf="!questions['questions-list'].length">Please select</option> <!-- show this if the list of questions hasn't been received. one is empty to prompt for user to make a selection-->
<!-- syntax of ngfor let <name-i-want-to-call-each-item> of <array-property-on-component> -->
<option *ngFor="let tag of supportedTags['supported-tags']">{{tag.course+"-"+tag.subject+"-"+tag.topic}}</option>
</select>
</div>
<app-show-errors [control]="languageSelectorForm.controls.tags"></app-show-errors>
</div>
<button type="submit" id="tags-submit-button" class="content-div__button--blue"> Submit! </button>
</form>
</div>
<div *ngIf="questions['questions-list'].length" class="practice-question-list-component-container" id="question-list-component"> <!-- this table takes second row-->
<table class="table table-hover table-bordered table-striped">
<thead class="thead-dark">
<tr>
<th style="width:10%" scope="column">Tag</th>
<th style="width:45%" scope="column">Question</th>
<th style="width:5%" scope="column"></th> <!-- for show more button -->
</tr>
</thead>
<tbody>
<tr *ngFor="let question of questions['questions-list'];let i = index ">
<td>{{ question.tag }}</td>
<td>{{ question.description}},{{question['question-id']}}</td>
<!--td *ngIf="!question.description">Description not available. {{}}</td--> <!--TODOM - remove this. It is a temp fix to show something in the table if description is empty-->
<!-- because index starts with 0, adding 1 to it while calculating button id-->
<!-- note passing of object {..}. Remember, objects are common in JS. Object is the actual data in memory with real values, not a class template-->
<td> <button [routerLink]="[questionDetailRouterLink, {'question-id':question['question-id']}]" id="{{'show-more-button-'+(i+1)}}" class="btn content-div__button--blue btn-sm">Show more</button></td>
</tr>
</tbody>
<button *ngIf="!this.lastPage" (click)="getNextPage()" id="next-page-button" class="btn content-div__button--blue btn-sm">Next Page</button>
</table>
</div>
</div>
I am initializing the questions
array in ngOnInit
ngOnInit(){
console.log("in question list on init. question is ",this.questions);
this.questionManagementService.tags$.subscribe((successResult:Result)=>{
console.log("got tags result",successResult);
if(successResult.result !== "initial") {
this.supportedTags = JSON.parse(successResult['additionalInfo']) as SupportedTags;
console.log("got tags: ", this.supportedTags);
console.log("no. of tags ",this.supportedTags["supported-tags"].length);
} else {
console.log("ignoring initial value");
}
},
(errorResult:Result)=>{
console.log("unable to get supported tags ",errorResult['additionalInfo']);
this.showDialog(new PracticeQuestionListContext(errorResult.additionalInfo, new PracticeQuestionListAdditionalInfo()));
});
this.questions= new PracticeQuestionsListAPI(new AdditionalPagingInfo("",new PartitionInfo(0,0)),
[]);
this.lastPage = false;
this.createForm();
let tagSubscription = this.questionManagementService.getSupportedTags(new TagId("coding"));
//TODOM - need to rate limit the size of response i.e. no. of entries in the result/array
let questionListSubscription = this.questionManagementService.questionsArray$.subscribe((result:Result)=>{
console.log('received result from question array observable',result);
if(result.result === "success") { //received response from server
let questionList = JSON.parse(result.additionalInfo) as PracticeQuestionsListAPI;
console.log("got list of questions value ", questionList);
this.questions['pagination-info'] = questionList['pagination-info'];
this.questions['questions-list'] = questionList['questions-list'];
if (questionList["questions-list"].length !== 0) { //server has send list of questions
this.questions['pagination-info']['page-state'] = questionList['pagination-info']['page-state'];
this.questions['pagination-info']['partition-info'] = questionList['pagination-info']['partition-info'];
this.questions['questions-list'] = questionList['questions-list'];
console.log("previous question filter is ",this.questionsFilter);
this.questionsFilter["pagination-info"]["page-state"]=questionList["pagination-info"]["page-state"];
this.questionsFilter["pagination-info"]["partition-info"].month=questionList["pagination-info"]["partition-info"].month;
this.questionsFilter["pagination-info"]["partition-info"].year=questionList["pagination-info"]["partition-info"].year;
console.log("new question filter is ",this.questionsFilter);
//TODOM - maybe this assignment below was causing memory leak. So changed this as above
//this.questionsFilter['pagination-info'] = questionList['pagination-info'];
this.lastPage = false; //the server indicates that there are no more questions by sending these values (no paging state and no partition info)
if (this.questions['pagination-info']['page-state'].length == 0 &&
this.questions['pagination-info']['partition-info'].year == 0 &&
this.questions['pagination-info']['partition-info'].month == 0) {
this.lastPage = true;
} else {//if the list is empty then there are no (more) questions for the selected tag
this.lastPage = false;
}
} else {
this.lastPage = true; //Don't show next button if there are no questions.
this.showDialog(new PracticeQuestionListContext("Reached end of the search. No more results available", new PracticeQuestionListAdditionalInfo()));
}
} else {
//TODOM - I should probably display the error in case there is an error from the server
console.log("ignoring value");
}
},
(err:Result)=>{
console.log("received error from QuestionArray observable",err);
//TODOM - probably should change the name of DialogContext to Component specific additional context
this.showDialog(new PracticeQuestionListContext(err.additionalInfo,new PracticeQuestionListAdditionalInfo()));
});
}
I believe the observable
my component is subscribing to sends the old values again when the new instance of the component subscribes to it. How can I make the observable not send the value again.
I am creating the observable in a service as follows.
this.questionsArray$ = this.questionsArraySubject.asObservable();
and am using next
to send the values
来源:https://stackoverflow.com/questions/58103125/angular-component-is-retaining-old-value-maybe-because-the-observable-is-resendi