Jesteś zadowolony z tego, co oferuje moduł nadrzędny w Akeneo PIM, ale zależy Ci na zmianie jednej z funkcjonalności? Jako Frontend Developer często będziesz stawać przed tego typu wyzwaniem, bowiem nie zawsze możliwe jest pokrycie wszystkich specyficznych potrzeb biznesowych za pomocą zainstalowanego modułu.
Z tego artykułu dowiesz się, jaka jest najprostsza i zarazem najlepsza metoda, by rozszerzyć moduł RequireJS, a także jak zaimportować w plikach "requirejs.yml" pierwotny oraz rozszerzony plik. Pojęcie dziedziczenia jest również ważne w tym kontekście, ponieważ właściwości i metody modułu nadrzędnego (niezmienione) są dziedziczone przez nasz moduł. Gotowy?
Przeczytaj również inne artykuły z cyklu:
- Akeneo PIM UI – Kompletny przewodnik dla Frontend Developerów
- Co powinieneś wiedzieć o strukturze modułów w Akeneo PIM opartych o RequireJS?
- Wprowadzenie do tworzenia modułów frontendowych w Akeneo PIM
- Jak nadpisać moduł oparty o RequireJS?
Nadpisywać czy rozszerzać?
Moduł modułowi jest nierówny. W przypadku większych modułów RequireJS, które posiadają liczne metody oraz są wykorzystywane w wielu miejscach aplikacji, nie najlepszą praktyką byłoby nadpisywanie ich, co było tematem naszego poprzedniego artykułu. Problem może stanowić też aktualizacja oprogramowania, w sytuacji gdy nadpisujemy złożony moduł.
Jeśli wymagane jest zmodyfikowanie lub dodanie tylko jednej wybranej metody w złożonym module opartym o RequireJS, powinieneś go rozszerzyć. Zaleta takiego podejścia jest oczywista. Rozszerzając domyślny moduł, nadpisujemy tylko te metody, które chcemy zmodyfikować, a nie całość.
Najlepsza praktyka przy rozszerzaniu modułu RequireJS
Wykorzystując dziedziczenie, będziemy chcieli rozszerzyć istniejący moduł RequireJS i zmienić logikę metody "createFields". Naszym celem będzie sprawdzenie, czy aktualne pole ma wartość "name" i przypisanie dla niego jakiejś domyślnej wartości.
Plik "attributes" jest sporym modułem, który występuje w wielu miejscach. Odpowiada za pobranie informacji o danych polach i nadanie im odpowiedniego kontekstu oraz wartości. Ponadto pomaga w sortowaniu ich w odpowiedniej kolejności. W ramach zadania musisz zmodyfikować metodę "createFields". Sprawdź dodatkowo w plikach "requirejs.yml", jak importowany jest domyślnie ten moduł.
Domyślnie dodawany jest w następujący sposób:
pim/form/common/attributes: pimui/js/form/common/attributes
Plik, który będziemy rozszerzać, znajdziesz tutaj:
Aby rozszerzyć istniejący moduł, należy go z zaimportować pod innym kluczem, a następnie dodać go do pliku, w którym rozszerzamy ten moduł. Na końcu rozszerzony moduł importujemy pod kluczem starego.
Plik "attributes.js" dodajemy w RequireJS pod nowym kluczem "base-attributes", upewniając się przy tym, że podany klucz nie jest nigdzie wykorzystywany w projekcie:
pim/form/common/base-attributes: pimui/js/form/common/attributes
Kolejnym krokiem jest stworzenie nowego pliku "attributes", który będzie rozszerzał stary. Do niego dodajemy pierwotny plik "attributes.js" pod kluczem "pim/form/common/base-attributes".
W podanym przypadku z pierwotnego pliku źródłowego kopiujemy tylko te metody, które chcemy rozszerzyć:
'use strict';
/**
* Override of the attributes module.
*
* Purpose of this override is to improve the blocking fields for simple products
* and sets of products including common attributes and variants
*
*/
define(
[
'jquery',
'underscore',
'oro/mediator',
'pim/field-manager',
'pim/attribute-manager',
'pim/fetcher-registry',
'pim/user-context',
'pim/security-context',
'pim/i18n',
'pim/form/common/base-attributes'
],
function (
$,
_,
mediator,
FieldManager,
AttributeManager,
FetcherRegistry,
UserContext,
SecurityContext,
i18n,
BaseAttributes
) {
return BaseAttributes.extend({
createFields: function (data, values) {
return FetcherRegistry.getFetcher('attribute')
.fetchByIdentifiers(Object.keys(values))
.then(attributes => {
attributes.sort((a, b) => {
if (a.sortOrder b.sortOrder) {
return -1;
}
if (a.sortOrder > b.sortOrder) {
return 1;
}
return a.meta.id b.meta.id ? -1 : 1;
});
return $.when.apply(
$,
attributes.map(attribute => {
console.log(values);
return this.createAttributeField(data, attribute.code, values[attribute.code]);
})
);
})
.then(function () {
return _.values(arguments);
});
}
});
}
);
Po zaimportowaniu pierwotny plik "attributes" jest dostępny pod nazwą "BaseAttributes". Dzięki użyciu "BaseAttributes.extend" mamy dostęp do wszystkich metod i właściwości zaimportowanego przez nas pliku.
Ostatni krok przed edycją samego pliku polega na dodaniu w "requirejs.yml" stworzonego przez nas pliku. Pamiętaj, aby plik został dodany pod tym samym kluczem, pod jakim pierwotnie był dodany rozszerzany przez nas moduł:
pim/form/common/base-attributes: pimui/js/form/common/attributes
pim/form/common/attributes: macopediaproduct/js/product/maco-attributes
W pierwszej linii dodany jest stary plik "attributes" dostępny pod kluczem "pim/form/common/base-attributes". W drugiej, pod kluczem "pim/form/common/attributes", importowany jest już nasz moduł rozszerzający domyślny plik "attributes".
Teraz możemy przystąpić do edycji stworzonego przez nas modułu. W metodzie "createFields", którą chcemy edytować, wykorzystajmy na razie polecenie "console.log" wyświetlające zmienną "values". To pomoże nam zweryfikować, czy plik został poprawnie dodany oraz do jakich danych mamy dostęp:
console.log(values);
Jeśli wszystko wykonaliśmy poprawnie, powinniśmy w narzędziach deweloperskich zobaczyć następujące informacje dla każdego pola:
Jak widać, mamy tutaj dostęp do wielu właściwości, a jedną z nich jest "name". Spróbujmy zatem dla pola "name" zmienić właściwość "name" dla wersji angielskiej:
'use strict';
/**
* Override of the attributes module.
*
* Purpose of this override is to improve the blocking fields for simple products
* and sets of products including common attributes and variants
*
*/
define(
[
'jquery',
'underscore',
'oro/mediator',
'pim/field-manager',
'pim/attribute-manager',
'pim/fetcher-registry',
'pim/user-context',
'pim/security-context',
'pim/i18n',
'pim/form/common/base-attributes'
],
function (
$,
_,
mediator,
FieldManager,
AttributeManager,
FetcherRegistry,
UserContext,
SecurityContext,
i18n,
BaseAttributes
) {
return BaseAttributes.extend({
createFields: function (data, values) {
return FetcherRegistry.getFetcher('attribute')
.fetchByIdentifiers(Object.keys(values))
.then(attributes => {
attributes.sort((a, b) => {
if (a.sortOrder b.sortOrder) {
return -1;
}
if (a.sortOrder > b.sortOrder) {
return 1;
}
return a.meta.id b.meta.id ? -1 : 1;
});
return $.when.apply(
$,
attributes.map(attribute => {
if (attribute.code === 'name') {
values['name'][1].data = 'New description...';
}
return this.createAttributeField(data, attribute.code, values[attribute.code]);
})
);
})
.then(function () {
return _.values(arguments);
});
}
});
}
);
Załączamy funkcję warunkową JEŻELI, która sprawdzałaby, czy aktualnym polem jest "name", następnie w "values" szukamy obiektu "name". W nim znajduje się kilka obiektów dla każdej wersji językowej. Nam zależy na nadpisaniu dla wersji angielskiej, stąd też wybieramy drugi obiekt i jemu przypisujemy nową wartość dla przykładu "New description…".
Teraz powinieneś być w stanie zobaczyć domyślną wartość pola "name" dodaną przez nas:
Czy kroki opisane w tym artykule okazały się pomocne? Bądź na bieżąco i śledź nas w mediach społecznościowych (Twitter / LinkedIn / Facebook)! W kolejnej odsłonie poznasz jeszcze jedno podejście do modyfikacji modułów w Akeneo PIM. W artykule wyjaśnimy szczegółowo, jak dodawać własne pliki i wykorzystać je w istniejących modułach RequireJS.