Настройка входного сигнала на компоненте в модальном окне ng bootstrap

Вопрос или проблема

В Angular 17.3 у меня есть компонент, который использует некоторые сигнальные входы, такие как

myInput = input(false);

Я хочу показать этот компонент в модальном окне, используя ng-bootstrap. Возможно ли это сделать и установить значение myInput? Я пробовал

private modalService = inject(NgbModal);

const modalRef = this.modalService.open(MyComponent);
modalRef.componentInstance.myInput = true;

как показано в документации bootstrap, но это, похоже, заменяет поле myInput, превращая его в булево значение вместо сигнала. Я пробовал

modalRef.componentInstance.myInput.set(true);

но выдается ошибка “modalRef.componentInstance.myInput.set is not a function”.

Вообще возможно ли это? Или это просто несовместимо с сигналами?

Согласно дизайну, сигнальные входы являются только для чтения. Вы можете установить новое значение только через привязку в шаблоне или через ComponentRef.setInput(). К сожалению, ng-bootstrap не предоставляет ComponentRef, но есть запрос на функцию для его добавления. Пока этого не произойдет, вы можете использовать простой signal(), который записывается, или основанный на декораторах @Input().

Поскольку input не может быть изменен, вы должны использовать либо signal, либо model, которые можно изменить.

Если вам нужно, чтобы компонент принимал входные данные [someInputSignal]="'test'" и обновлялся через ng-bootstrap, используйте модальное окно (до тех пор, пока не будет поддержан input signal setInput), если нет, используйте обычный сигнал.

Модульные входы – Сигналы

Мы можем установить модель для приема входов

@Component({
  selector: 'ngbd-modal-content',
  standalone: true,
  template: `
        {{someInputSignal()}}
    `,
})
export class NgbdModalContent {  
  someInputSignal: ModelSignal<string> = model('');
  ...
}

Затем в методе открытия используйте set, чтобы установить значение сигнала.

    open() {
        const modalRef = this.modalService.open(NgbdModalContent);
        const comp: NgbdModalContent = modalRef.componentInstance;
        comp.someInputSignal.set('это работает!');
    }

Полный код:

import {
  Component,
  inject,
  input,
  ModelSignal,
  InputSignal,
  Input,
  signal,
  model,
} from '@angular/core';
import { NgbActiveModal, NgbModal } from '@ng-bootstrap/ng-bootstrap';

@Component({
  selector: 'ngbd-modal-content',
  standalone: true,
  template: `
        {{someInputSignal()}}
    `,
})
export class NgbdModalContent {
  activeModal = inject(NgbActiveModal);

  someInputSignal: ModelSignal<string> = model('');
  @Input() some: string = '';

  ngOnInit() {}
}

@Component({
  selector: 'ngbd-modal-component',
  standalone: true,
  templateUrl: './modal-component.html',
})
export class NgbdModalComponent {
  private modalService = inject(NgbModal);

        open() {
            const modalRef = this.modalService.open(NgbdModalContent);
            const comp: NgbdModalContent = modalRef.componentInstance;
            comp.someInputSignal.set('это работает!');
        }
}

Демо на Stackblitz

Ответ или решение

Вопрос: Как настроить входной сигнал в компоненте модального окна ng-bootstrap?

Вопрос, который вы задаете, действительно актуален для разработчиков, использующих Angular 17.3 с библиотекой ng-bootstrap для модальных окон. Вы столкнулись с проблемой возможности передачи значений сигналов в компоненты, открываемые через сервис модальных окон. Давайте детально разберем, как можно обойти существующие ограничения.

Проблема с сигналами в Angular

Сигналы в Angular предоставляют мощный способ управления состоянием, однако у них есть ограничения. Основное из них заключается в том, что входные сигналы являются только для чтения, что означает, что вы не можете изменять их напрямую после передачи в компонент. В вашем случае:

myInput = input(false);

При попытке установить значение сигнала через:

modalRef.componentInstance.myInput = true;

вы фактически перезаписываете сигнал, и он теряет свою первоначальную структуру, что вызывает путаницу.

Решение через использование ModelSignal

Чтобы обойти эти ограничения, вы можете использовать ModelSignal, который допускает изменение после инициализации. Вместо того чтобы использовать input, создайте модель для вашего входного сигнала.

Вот как это может выглядеть:

  1. Определите модель сигнала в вашем компоненте модального окна:
import { Component, inject, model } from '@angular/core';
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';

@Component({
  selector: 'ngbd-modal-content',
  template: `
    {{someInputSignal()}}
  `,
})
export class NgbdModalContent {
  activeModal = inject(NgbActiveModal);

  someInputSignal: ModelSignal<string> = model('');
}
  1. В основном компоненте, который открывает модал, измените метод открытия модального окна так, чтобы он использовал метод set для изменения значения сигнала:
import { Component, inject } from '@angular/core';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { NgbdModalContent } from './ngbd-modal-content.component';

@Component({
  selector: 'ngbd-modal-component',
  templateUrl: './modal-component.html',
})
export class NgbdModalComponent {
  private modalService = inject(NgbModal);

  open() {
    const modalRef = this.modalService.open(NgbdModalContent);
    const comp: NgbdModalContent = modalRef.componentInstance;
    comp.someInputSignal.set('it works!');
  }
}

Преимущества использования ModelSignal

Использование ModelSignal позволяет вам динамически обновлять значение сигнала непосредственно внутри вашего модального окна. Это делает ваш код более гибким и поддерживаемым. Кроме того, такое решение будет совместимо с будущими обновлениями Angular, которые могут улучшить интеграцию сигналов.

Заключение

Таким образом, хотя сигналы в Angular могут показаться ограничительными на первый взгляд, использование ModelSignal предоставляет решение, которое позволяет вам эффективно управлять состоянием в ваших компонентах. Не забывайте следить за обновлениями библиотеки, так как со временем могут появиться новые возможности для работы с сигналами и компонентами. Если вам нужна дополнительная информация или помощь, не стесняйтесь обращаться к документации Angular и ng-bootstrap, а также к сообществу разработчиков.

Оцените материал
Добавить комментарий

Капча загружается...