Решено! Я добавил onChange, как предложил @webdevius:
Добавил onChange в HTML-код моей панели
<div class="filter-multiselect">
<p-multiSelect [options]="items"
[(ngModel)]="itemsSelected"
styleClass="multiSelect"
[defaultLabel]="labelComponent"
(onPanelShow)="handlePanelShow()"
(onPanelHide)="handlePanelHide()"
(onChange)="filtersApply()"
panelStyleClass="panelStyleClassCustom"
[ngClass]="isOpen ? 'multi-select-open' : '' "
[maxSelectedLabels]="0">
<ng-template let-element let-i="index" pTemplate="item">
<div class="ui-multiselect-item-text">{{element.label}}</div>
</ng-template>
</p-multiSelect>
</div>
и генерирую при выборе фильтра (теперь это не зависит открыта ли панель или нет)
import { Component, OnInit, ViewEncapsulation, Input, ElementRef, EventEmitter, Output } from '@angular/core';
import { MultiselectBaseModel } from '../app-models/MultiselectBaseModel';
@Component({
selector: 'app-filter-multiselect',
templateUrl: './filter-multiselect.component.html',
styleUrls: ['./filter-multiselect.component.less'],
encapsulation: ViewEncapsulation.None
})
export class FilterMultiselectComponent implements OnInit {
@Input() labelComponent: string;
@Input() items: MultiselectBaseModel[];
@Input() itemsSelected: MultiselectBaseModel[];
@Output() closeMultiselectEventHandler: EventEmitter<any> = new EventEmitter();
isOpen = false;
constructor(public el: ElementRef) { }
ngOnInit() {}
handlePanelShow() {
this.isOpen = true;
}
handlePanelHide() {
this.isOpen = false;
}
filtersApply() {
this.closeMultiselectEventHandler.emit(this.itemsSelected);
}
handleClickMultiSelect(event) {
}
}
If you need to remove items that aren't on the top, then you need something other than a stack.
Try making your own implementation of a stack from a List. Then you get to implement your own push and pop functions (add & remove on the list), and your own special PopFromTheMiddle function.
For example
public class ItsAlmostAStack<T>
{
private List<T> items = new List<T>();
public void Push(T item)
{
items.Add(item);
}
public T Pop()
{
if (items.Count > 0)
{
T temp = items[items.Count - 1];
items.RemoveAt(items.Count - 1);
return temp;
}
else
return default(T);
}
public void Remove(int itemAtPosition)
{
items.RemoveAt(itemAtPosition);
}
}
Рассмотрите возможность использования другого контейнера. Может быть, LinkedList. Затем вы можете использовать
AddFirst AddLast RemoveLast RemoveFirst
так же, как pop / push из стека, и вы можете использовать
Remove
, чтобы удалить любой узел из середины списка
Возможно, метод расширения будет работать, хотя, я подозреваю, что совершенно необходима другая структура данных полностью.
public static T Remove<T>( this Stack<T> stack, T element )
{
T obj = stack.Pop();
if (obj.Equals(element))
{
return obj;
}
else
{
T toReturn = stack.Remove( element );
stack.Push(obj);
return toReturn;
}
}
В истинном стеке это можно сделать только одним способом -
Высовывать все предметы, пока вы не удалите тот, который вы хотите, затем поместите их обратно в стек в соответствующем порядке.
Однако, это не очень эффективно.
Если вы действительно хотите удалить из любого места, я бы рекомендовал создать псевдостек из списка, LinkedList или какой-либо другой коллекции. Это даст вам возможность легко это сделать.
Stack temp = new Stack();
object x, y;
While ((x = myStack.Pop()) != ObjectImSearchingFor)
temp.Push(x);
object found = x;
While ((y = temp.Pop()) != null)
myStack.Push(y);
Тогда это не стек, верно? Стек является ПОСЛЕДНИМ в ПЕРВОМ из
.
Вам придется написать пользовательский или выбрать что-то другое.
хмммм ...... Я согласен с предыдущими двумя ответами, но если вы хотите взломать свой путь, просто выталкивайте и сохраняйте все элементы до тех пор, пока не доберетесь до нужного, и повторите их все
Да, это уродливый, плохо работающий, возможно, странный код, который потребует длинного комментария, объясняющего почему, но вы могли бы сделать это .. ..