Мне кажется, что этот вопрос мне задавали раньше в другой форме, но я не могу найти хороший и прямой ответ, поэтому решил, что задам вопрос.
Я создаю приложение Angular, которое имеет ряд компонентов, которые должны иметь возможность контролировать свое собственное внутреннее состояние (если оно не подключено к какому-либо глобальному или локальному состоянию) и получать свое состояние из внешних данных.,
Для пояснения приведу пример.У меня есть страница, которая отображает набор фильтров, которые фильтруют массив содержимого (в другом месте).Фильтры принимают разные формы, одна из которых - флажки.
Поэтому я создал компонент флажка, который выглядит следующим образом:
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
/** A simple styled checkbox component, which emits on change. */
@Component({
selector: 'app-checkbox',
templateUrl: './checkbox.component.html',
styleUrls: ['./checkbox.component.scss']
})
export class CheckboxComponent implements OnInit {
/** Label to apply to checkbox in HTML */
@Input() public name = '';
/** Whether the checkbox is disabled (non-clickable). */
@Input() public disabled = false;
/** Any additional CSS class to apply. */
@Input() public class = '';
/** Function called on click. Fed object with checkbox name and value. */
@Output() change = new EventEmitter();
/** Whether the checkbox is checked. */
@Input() checked = false;
constructor() { }
ngOnInit() {}
/** Selects or deselects the checkbox on click. */
onClick() {
this.checked = !this.checked;
this.change.emit({ checked: this.checked, name: this.name });
}
}
Я не думаю, что HTML сильно поможет.Я использую этот компонент в большинстве мест, передавая его значение checked
, основанное на некотором внешнем значении, поступающем из общего сервиса (или данных родительского компонента), и обновляя переданные данные по щелчку.
У меня два вопроса:
Хотя этот флажок может использоваться только в ситуациях, когда его значение читается извне, в настоящее время я также использую его в«библиотека» компонента, которая просто показывает взаимодействия пользовательского интерфейса, поэтому в идеале я бы хотел, чтобы компонент (и другие) мог сам переключаться, если не прошел функцию изменения (таким образом this.checked = !this.checked
).Но если я сделаю это, то для значения checked
флажка появится два источника правды - его собственное внутреннее состояние и любое внешнее состояние, измененное функцией change
(в небиблиотечных контекстах). Как мне создать компонент, который вызывает функцию change
, если она дана, но обрабатывает ее класс внутренне, если нет? У меня возникают проблемы, в частности, обнаружение, была ли передана такая функция,и хотя я предполагаю, что мог бы передать дополнительный логический атрибут, который кажется дублирующим и грязным.
Я столкнулся с проблемами, когда компонент не обновляется, когда соответствующая службаизменения данных.В частности, у меня есть один и тот же флажок фильтра в двух отдельных модалах, и если я изменю его в одном, он изменит другой, но потом, когда я перейду к этому другому модалу и верну его обратно, изменение не синхронизируетсяна другой (оригинальный) модал.Мне кажется, что компонент получает свое значение от службы при монтировании (например, при монтировании модального), но он не слушает изменение данных и реагирует соответствующим образом.(Предполагается, что модалы не выглядят полностью размонтированными).Но в целом я не совсем уверен, как это работает, или должен. Как заставить компоненты Angular «прослушивать» изменения в служебных данных?
My FiltersService
ниже, чтобы дать вам представление о том, как яЯ пытался ответить на этот вопрос:
import { Injectable } from '@angular/core';
export interface Filter { name: string; value: any; }
/** Tracks and updates status of car filters throughout application. */
@Injectable({
providedIn: 'root'
})
export class FiltersService {
/** Object of filters, with name pointing to value (any). */
filters: object = {};
constructor() { }
/** Sets an object of filters (one or more) at once. */
set(filters: object) {
this.filters = Object.assign(this.filters, filters);
return this.filters;
}
}
Есть ли смысл того, что я делаю неправильно, что мешает компоненту реагировать на изменения данных службы?Вот пример того, как я рендерил компонент (setLocalFilters
изменяет объект локально по отношению к родительскому компоненту, который затем обновляет сервис при отправке), а localFilters
в основном является копией данных сервиса глобальных фильтров, которые яподтверждено, как я и ожидал:
<app-checkbox
name={{option}}
(change)="setLocalFilter($event.name, $event.checked)"
[checked]="localFilters[option]"
></app-checkbox>
Я понимаю, как службы / компоненты должны взаимодействовать правильно?Не очень знаком с этим типом поведения в Angular (или с Angular) и был бы признателен за любые указатели.
Спасибо!