У меня есть родительский компонент, который перебирает массив объектов и отображает дочерние компоненты.
Дочерний компонент имеет два входных параметра: text
и terms
. Итак, HTML родительского компонента имеет вид:
<div *ngFor="let item of items">
<childComponent [text]='item.text' [terms]='item.terms' />
</div>
Исходя из некоторых взаимодействий с пользователем, в родительском компоненте список элементов обрабатывается и изменяется, и требуется заново отобразить весь родительский / дочерний элемент компоненты.
Поскольку это Angular, все, что я делаю, это изменяю items
в качестве базовой модели, и я ожидаю, что все дочерние компоненты будут автоматически отражать изменения в представлении / пользовательском интерфейсе.
И я вижу, что terms
все обновляются во всех дочерних компонентах, но text
не обновляется и используется старое значение.
Я использовал onOnChanges
ловушку жизненного цикла, регистрировал изменения и понял, что только * Параметр 1018 * отслеживается как изменение, а text
не отслеживается.
Что может быть не так?
Обновление :
С мы используем UMD и транспортер, отличный от CLI, веб-пакета и обычного набора инструментов, поэтому код сильно отличается. Но в родительском компоненте после обработки я делаю эту строку:
this.items = newItems;
Обновление 2 :
Это код моего родительского компонента:
var ContextPartialTranslation = (function () {
function ContextPartialTranslation() {
var _this = this;
_this.loadEntity();
_this.handleWordIsSetAsKnown();
}
ContextPartialTranslation.prototype.handleWordIsSetAsKnown = function () {
var _this = this;
waitAndRun('app.wordIsSetAsKnown', function () {
app.wordIsSetAsKnown.subscribe(function (term) {
console.log(term);
_this.removeWordFromNewWordsList(_this.originalData, term);
_this.setData(_this.originalData);
});
});
};
ContextPartialTranslation.prototype.removeWordFromNewWordsList = function (object, term) {
var _this = this;
if (!object) {
return;
}
if (typeof object !== "object") {
return;
}
for (property in object) {
if (property === "newWords") {
object[property] = object[property].filter(function (item) { return item['term'].toLowerCase() !== term.toLowerCase() });
}
else {
_this.removeWordFromNewWordsList(object[property], term);
}
}
};
ContextPartialTranslation.prototype.loadEntity = function (entityGuid, previousEntityGuid) {
var _this = this;
// loading data from API, then calling setData using JSON returned from API
};
ContextPartialTranslation.prototype.setData = function (data) {
var _this = this;
_this.readingStats = null;
_this.content = null;
_this.entity = null;
_this.readingStats = data.readingStats;
_this.content = data;
_this.entity = data.entity;
console.log('new enttiy', _this.entity);
};
ContextPartialTranslation = __decorate([
ng.core.Component({
selector: 'contextPartialTranslation',
templateUrl: '/context/partialTranslationHtml',
preserveWhitespaces: true
}),
__metadata("design:paramtypes", [])
], ContextPartialTranslation);
ContextPartialTranslation.parameters = [];
return ContextPartialTranslation;
}());
И это код моего дочернего компонента:
var OriginalText = (function () {
function OriginalText() {
var _this = this;
}
OriginalText.prototype.ngOnChanges = function (changes) {
var _this = this;
console.log(changes);
_this.html = app.sanitizer.bypassSecurityTrustHtml(_this.addStyleToNewWordsInsideText(_this.html, _this.newWords));
};
OriginalText.prototype.addStyleToNewWordsInsideText = function (text, newWords) {
if (!text) {
text = '';
}
if (!newWords) {
newWords = [];
}
tempNewWords = newWords.map(function (i) { return i.term; });
var allWords = [];
var regex = /\b[a-zA-Z]{2,}\b/gi;
var match = true;
while (match) {
match = regex.exec(text);
if (match && tempNewWords.indexOf(match.toString()) === -1) {
allWords.push(match.toString());
}
}
tempNewWords = tempNewWords.filter(function onlyUnique(value, index, self) {
return self.indexOf(value) === index;
});
allWords = allWords.filter(function onlyUnique(value, index, self) {
return self.indexOf(value) === index;
});
for (var x = 0; x < allWords.length; x++) {
text = text.replace(new RegExp('\\b' + allWords[x] + '\\b', 'gi'), function (newWord) {
return '<span class="word" onclick="app.showWordDialog(\'' + newWord + '\')">' + newWord + '</span>';
});
}
for (var y = 0; y < tempNewWords.length; y++) {
text = text.replace(new RegExp('\\b' + tempNewWords[y] + '\\b', 'gi'), function (newWord) {
return '<span class="newWord">' + newWord + '</span>';
});
}
return text;
};
__decorate([
ng.core.Input(),
__metadata("design:type", String)
], OriginalText.prototype, 'html', void 0);
__decorate([
ng.core.Input(),
__metadata("design:type", String)
], OriginalText.prototype, 'newWords', void 0);
OriginalText = __decorate([
ng.core.Component({
selector: 'originalText',
templateUrl: '/language/originalText',
preserveWhitespaces: true
}),
__metadata("design:paramtypes", [])
], OriginalText);
OriginalText.parameters = [];
return OriginalText;
}());
И вот как я использую дочерний компонент внутри родительского компонента:
<mat-card class="center marginTop title-container main-title">
<mat-card-header *ngIf="entity?.title">
<mat-card-title>
<div [ngStyle]="{ 'background-image': 'url(' + entity.relatedItems.photos[0].relatedItems.url + ')'}" id="partialTranslation_Background" class="background"></div>
<p class="title">
<originalText [html]="entity.title" [newWords]="entity.relatedItems.newWords"></originalText>
</p>
<newWords [list]="entity.relatedItems.newWords" style="position: relative; z-index: 1;"></newWords>
</mat-card-title>
<mat-card-subtitle class="align-center" style="margin-top: 8px;">Cooking Time: {{ entity?.cookingTimeInMinutes }} Minutes ● Calories: {{ entity?.calories }}</mat-card-subtitle>
</mat-card-header>
</mat-card>
<mat-card class="center marginTop image-container">
<div class="background" [ngStyle]="{ 'background-image': 'url(' + entity.relatedItems.photos[0].relatedItems.url + ')'}"></div>
<img src="{{ entity.relatedItems.photos[0].relatedItems.url }}" />
</mat-card>
Наиболее важные части:
setData
в родительском компоненте ngOnChange
в дочернем компоненте <originalText [html]="entity.html"