Один из входных параметров компонента не обновляется в Angular - PullRequest
2 голосов
/ 23 марта 2020

У меня есть родительский компонент, который перебирает массив объектов и отображает дочерние компоненты.

Дочерний компонент имеет два входных параметра: 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"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...