Wewnątrz mojego projektu Angular (4 + Dokument) użyłem już przygotowanego komponentu (nie ma to znaczenia, ponieważ sposób rozszerzenia ControlValueAccessor jest taki sam, ale jeśli to ma znaczenie, użyłem ng2-select), które chciałem ze względu na lepszy UX i ładniejszy wygląd. Po włączeniu go do mojego komponentu formularza, który używa formularzy reaktywnych, zobaczyłem, że po przesłaniu wracam (dla formantu) obiekt oparty na klasie SelectItem, która jest używana wewnątrz przygotowanego komponentu, do zarządzania wybranymi przedmiotami - takimi jak:Angular 4 ControlValueAccessor wartości przy zgłaszaniu i zmianach wartości zdarzeń
// console.log(this.myForm.values)
Object {
txtInput: 'value',
// ...
preparedComponent: SelectItem { // <--
id: '1',
text: 'Chosen item'
}
}
Ponieważ składnik jest w zasadzie tylko zamiennik standardowego wyboru sterowania, spodziewałem się, że będę wracać identyfikator wybranej pozycji utworzone jako ciąg - tak:
// console.log(this.myForm.values)
Object {
txtInput: 'value',
// ...
preparedComponent: '1' // <--
}
Po I dowiedziałem się, czym właściwie jest ControlValueAccessor i jak to działa, zmieniłem sposób, który powraca po przesłaniu (lub lepiej powiedzieć o zmianie pozycji - onChange
) do identyfikatora przedmiotu. Problem został rozwiązany przez pewien czas, dopóki nie rozpocząłem ustawiania wstępnie zdefiniowanych wartości (przy edycji instancji), aby utworzyć formanty zamiast pustych wartości (na dodawanie instancji). Uznałem, że tym razem writeValue
przypisuje wartości do formowania w oparciu o to, co jest wysyłane do niego jako predefiniowana wartość. Tak więc w przypadku, gdy wysłałem wcześniej zdefiniowaną wartość jako ...
Object {
id: '1',
text: 'Chosen item'
}
... była to również wartość w Object przy przesyłaniu, tak jak w pierwszym przykładzie kodu powyżej. Zrobiłem obejście tego problemu, aby przypisać poprawną wartość do kontroli z onChange
zaraz po wywołaniu writeValue
. To był naprawdę niewłaściwy sposób to zrobić, ale nie mogę zorientowali się, że coś innego niż:
public writeValue(val: any): void {
this.selectedItems = val; // val is for example Object { id: '1', text: 'Chosen item' }
setTimeout(() => {
this.onChange(val.id); // just an example of emitted value, there should be some checks val is object and id exists in real code
}, 0);
}
A że pracował również w miarę nie zacząć subskrybować tworzą kontrola na valueChanges
. Problem polega na tym, że przy każdorazowym przypisywaniu wstępnie zdefiniowanej wartości do przygotowanego komponentu istnieje również emisja wartości użytej po przesłaniu, z powrotem do subskrybentów, nawet przy użyciu { emitEvent: false }
.
To są rzeczy, które chcę w jakiś sposób obsłużyć przygotowanym komponentem, ponieważ chcę uzyskać odpowiednią wartość z kontroli przy przesyłaniu i nie chcę zmiany emisji dla abonentów, dopóki wartość nie zostanie naprawdę zmieniona, a nie tylko zastąpione jako wartość predefiniowana. Każdy pomysł, jak sobie z tym poradzić, zostanie doceniony.
Przeszedłem dokładnie ten proces. Nie jestem do końca pewien, czy rozumiem dokładnie ten problem. – Amit
Problem dotyczy głównie 'onChanges' wewnątrz' writeValue'. Po pierwsze dlatego, że 'setTimeout', który jest naprawdę ostatnią rzeczą, którą robiłbym jako obejście, a po drugie dlatego, że emituje zdarzenie change po zainicjowaniu z predefiniowaną wartością. Idealnie wartości wejściowe i wyjściowe byłyby rozdzielone - Input zaakceptowałby obiekt, a Output zwrócił identyfikator wybranego obiektu. W związku z tym nie ma potrzeby wprowadzania zmian na wartość init, ponieważ nie jest to oczekiwane zachowanie domyślne (w przypadku '{emitEvent: false}' na 'setValue' kontroli lub formularza' reset' Angular nie emituje zdarzenia przy wartości przełączania). – user1257255
Jestem przekonany, że to bardziej problem, ponieważ jesteś (i ja też) "walczę" z ng2-select (który jest ledwo utrzymany) – Amit