Angular - синхронизация внутреннего и внешнего состояния компонента - PullRequest
0 голосов
/ 04 декабря 2018

Мне кажется, что этот вопрос мне задавали раньше в другой форме, но я не могу найти хороший и прямой ответ, поэтому решил, что задам вопрос.

Я создаю приложение 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) и был бы признателен за любые указатели.

Спасибо!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...