Как я могу запустить код после запуска knockoutjs в adminhtml

11

ОБНОВЛЕНИЕ : Вы можете получить доступ к моделям просмотра напрямую. Если вам нужно запустить код для запуска после рендеринга, используйте MutationObserver. Я опубликую свой код, как только у меня будет хороший рабочий пример.

Оригинальный вопрос: у нас много заказов по телефону. Я работаю над модулем, который автоматически заполняет данные в admin -> customer -> create new из нашего решения CRM, используя вызов webapi / jsonp. Таким образом, данные в magento не создают дубликаты данных, которые мы уже сохранили в нашей «основной базе данных».

Одна из задач, которую мне еще предстоит сделать, - добавить адрес (а) клиента. Сначала это казалось простым, пока я не осознал, что knockoutjs + magentojs отображает все в форме клиента и не позволяет мне захватывать шаблонные элементы. У меня есть чертовски много времени, пытаясь захватить наборы полей (входные элементы) после удаления всех адресов программно и создания новых.

Если вы удивляетесь, почему я так поступаю, часть моего кода всплывает и выглядит так: «Эй, этот человек уже существует. Вы хотите их использовать?» и он удаляет все, что вы уже набрали, и заменяет его правильной информацией. Тогда колл-центр подтверждает это, йадда йадда.

Я поделюсь кодом, который у меня есть, но он работает не совсем правильно. К вашему сведению, это расширяет Abstract для того, чтобы перехватить событие onUpdate. Не ругайте меня за попытку получить доступ к коллекции внутри элемента коллекции. Я не могу придумать лучший способ отловить событие onUpdate и все же посмотреть на все поля.

Я также полностью понимаю, что не так, я просто не знаю, как обойти это. Что не так, я предположил, что элементы, сгенерированные вызовом .activate (), будут немедленно доступны в следующем

document.getElementsByClassName ( 'admin__fieldset')

Это просто неправильная логика. В идеале, мне бы хотелось иметь возможность извлекать содержимое набора полей, не прибегая к этой хитрости пользовательского интерфейса, а затем, как только я все настрою, просто сделаю это.

Я не хочу прибегать к хаки JQuery, чтобы следить за обновлениями DOM.

// jsonService variable is available here because it is in the php template render. see
// Stti/Customer/view/adminhtml/templates/javascriptinject.phtml

define(['ko','jquery','underscore','originalAbstract','uiElement', 'uiCollection'], function(ko, $, _, Abstract, Element, Collection) {
    "use strict";

    var theArray = {
        formFields: [],
        getKnockout: (function (ko) {
            return ko;
        })(ko),
        addressButton: null,
        populateFormFields: function () {
            this.formFields = [];

            // Populate the addressButton thinger
            this.addressButton = this.getNewAddressButton();

            var cb = (function(formFields){
                return function (data) {
                    cr(data, formFields);
                }
            })(this.formFields);

            var cr = function (data, formFields) {
                var elems = data.elems();
                for (var i = elems.length - 1; i >= 0; i--) {
                    if (elems[i].hasOwnProperty('uid')) {
                        formFields.push(elems[i]);
                    }
                }
            };

            var fieldsets = document.getElementsByClassName('admin__fieldset');
            for (var i = fieldsets.length - 1; i >= 0; i--) {
                var data = this.getKnockout.dataFor(fieldsets[i]);
                cb(data);
            }

        },
        cleanupAddresses: function () {
            // Remove all addresses
            var fieldsets = document.getElementsByClassName('admin__fieldset');
            for (var i = fieldsets.length - 1; i >= 0; i--) {
                var data = this.getKnockout.dataFor(fieldsets[i]);
                if (data.dataScope.indexOf('data.address') !== -1 && data.childType === 'group') {
                    data.destroy();
                }
            }
        },
        getNewAddressButton: (function () {
            var retVal = null;
            var customerItem = null;

            // Make sure the template is loaded

            var fieldsets = document.getElementsByClassName('admin__page-nav-item');
            for (var i = fieldsets.length - 1; i >= 0; i--) {
                var data = this.getKnockout.dataFor(fieldsets[i]);
                if (data.dataScope === 'data.address') {
                    data.activate();
                } else {
                    customerItem = data;
                }
            }

            // AT THIS POINT, I REALLY WANT KNOCKOUT TO RENDER.  
            fieldsets = document.getElementsByClassName('admin__fieldset');
            for (var i = fieldsets.length - 1; i >= 0; i--) {
                var data = this.getKnockout.dataFor(fieldsets[i]);
                var elems = data.elems();
                if (elems.length === 1 && data.dataScope === 'data.address' && data.index === 'address') {
                    retVal = elems[0];
                }
            }

            // Return the user to the Account Information section
            if (customerItem !== null) {
                //customerItem.activate();
            }

            return retVal;
        }),
        addNewAddress: function () {
            var retVal = null;

            // Use the addressButton to add a child address
            if (this.addressButton) {
                retVal = this.addressButton.addChild();
            }

            this.populateFormFields();

            return retVal;
        },
        onUpdate: function (newValue) {
            if (newValue) {
                this.clearAllFields();
                switch (this.index) {
                    case "email":
                        this.handleEmailBlur(newValue);
                        break;
                    case "constit_id":
                        this.handleConstitBlur(newValue);
                        break;
                }
            }
        },
        handleEmailBlur: function (newValue) {
            // Don't look up anything if the box was cleared out
            if (newValue != null || newValue != '') {
                this.clearAllFields();
                this.makeJsonReq("GetIndividualByEmail?emailaddress=" + newValue + '&callback=?');
            }
        },
        handleConstitBlur: function (newValue) {
            // Don't look up anything if the box was cleared out
            if (newValue != null || newValue != '') {
                this.clearAllFields();
                this.makeJsonReq("GetIndividualByConstit?constit=" + newValue + '&callback=?');
            }
        },
        jQueryByIndex: function (index) {
            function findUIDbyIndex(element) {
                return element.index === index;
            }

            return $('#' + this.formFields.find(findUIDbyIndex).uid);
        },
        makeJsonReq: function (callString) {
            var msg = null;

            $.getJSON(jsonService + callString, (function (localData) {
                    return function (data) {
                        doWork(data, localData);
                    }
                })(this)
            ).done(function () {
                console.log("Json Request Successful");
            }).fail(function () {
                console.log("Json Request Fail");
            }).always(function () {
                if (msg != "") {
                    alert(msg);
                }
            });


            function doWork(individual, localData) {

                // create as many addresses as the individual has
                if (individual != null) {
                    if (individual.NKIUserId != null) {
                        if (individual.NKIUserId != "") {
                            msg = "WARNING! Netforum reports this user has been added to magento with ID " + individual.NKIUserId + ". LOOKUP THE CUSTOMER FIRST AND CONFIRM YOU WANT TO ADD A NEW CUSTOMER!";
                        }
                        //window.location = "/admin";
                    }

                    if (individual.ConstitID != null) {
                        msg = localData.populateFields(individual, localData);
                    }
                    else {
                        msg = "Individual could not be found in NetForum. Verify that this IS a new customer.";
                    }
                }
                else {
                    msg = "Customer's email was not found in netforum. Be sure to use the correct constituent ID if this is an existing customer. A new Netforum customer will be created if it is blank or incorrect.";
                    // prepFormNoUser("constit");

                }
            }

        },
        populateFields: function (individual, localData) {
            // This function is used to get jquerySelector by index

            var getField = localData.jQueryByIndex;

            if (localData.jQueryByIndex('email')) {
                localData.jQueryByIndex('email').val = individual.PrimaryEmailAddress;
            }

            var addresses = null;
            var mageAddresses = [];

            if (individual.Addresses) {
                addresses = individual.Addresses;

                // Populate the form with the addresses
                for (var i = 0; i < addresses.length; i++) {
                    mageAddresses.push(localData.addNewAddress());
                }
debugger;
                var primaryAddress = null;
                for (var i=0; i < addresses.length; i++) {
                    addresses.each(function (e) {
                        try {
                            if (e.IsPrimary) {
                                primaryAddress = e;
                            }

                        } catch (err) {
                            // todo: handle errors
                        }

                        // Populate the billing address if we are on the order screen
                        if (primaryAddress.Id) {
                            if ($('order-billing_address_cxa_key')) {
                                $('order-billing_address_cxa_key').value = primaryAddress.Id;
                                $('order-billing_address_cxa_key').disable();
                            }
                        }
                        if (primaryAddress.Line1) {
                            if ($('order-billing_address_street0')) {
                                $('order-billing_address_street0').value = primaryAddress.Line1;
                            }
                        }
                        if (primaryAddress.City) {
                            if ($('order-billing_address_city')) {
                                $('order-billing_address_city').value = primaryAddress.City;
                            }
                        }
                        if (primaryAddress.Zip) {
                            if ($('order-billing_address_postcode')) {
                                $('order-billing_address_postcode').value = primaryAddress.Zip;
                            }
                        }
                        if (individual.PrimaryPhoneNumber) {
                            if ($('order-billing_address_telephone')) {
                                $('order-billing_address_telephone').value = individual.PrimaryPhoneNumber;
                            }
                        }

                    });
                }
            }

            if (individual.MemberType != null) {
                if ($('group_id')) {
                    var options = $$('select#group_id option');
                    if (individual.MemberType > 0) {
                        options[3].selected = true;
                        $('signup_method').value = "ADMIN-NEWORDER-EXISTING-MEMBER";
                    }
                    else {
                        options[0].selected = true;
                        $('signup_method').value = "ADMIN-NEWORDER-EXISTING-NONMEMBER";
                    }

                    $('signup_method').disable();

                }

                if ($('_accountconstit_id')) {
                    var options = $$('select#_accountgroup_id option');
                    if (individual.MemberType > 0) {
                        options[3].selected = true;
                        $('_accountsignup_method').value = "ADMIN-NEWCUSTOMER-EXISTING-MEMBER";

                    }
                    else {
                        options[0].selected = true;
                        $('_accountsignup_method').value = "ADMIN-NEWCUSTOMER-EXISTING-NONMEMBER";
                    }

                    $('_accountsignup_method').disable();
                }
            }

            if ($('_accountcst_key')) {
                $('_accountcst_key').value = individual.Id;
                $('_accountcst_key').disable();
            }
            if ($('cst_key')) {
                $('cst_key').value = individual.Id;
                $('cst_key').disable();
            }


            if (individual.FirstName) {
                if ($('_accountfirstname')) {
                    $('_accountfirstname').value = individual.FirstName;
                }
                if ($('order-billing_address_firstname')) {
                    $('order-billing_address_firstname').value = individual.FirstName;
                }
            }
            if (individual.LastName) {
                if ($('_accountlastname')) {
                    $('_accountlastname').value = individual.LastName;
                }
                if ($('order-billing_address_lastname')) {
                    $('order-billing_address_lastname').value = individual.LastName;
                }
            }
            if (individual.MiddleName) {
                if ($('_accountmiddlename')) {
                    $('_accountmiddlename').value = individual.MiddleName;
                }
                if ($('order-billing_address_middlename')) {
                    $('order-billing_address_middlename').value = individual.MiddleName;
                }
            }

            if (individual.DateOfBirth) {
                var dob = new Date(parseInt(individual.DateOfBirth.substr(6)));
                var fDob = dob.toString('MM-dd-yyyy');
                if ($('_accountdob')) {
                    $('_accountdob').value = fDob;
                }
            }

            return msg;
        },
        clearAllFields: function () {
            var inputs = $(':input');
            for (var i = 0; i < inputs.length; i++) {
                inputs[i].value = '';
            }

            this.cleanupAddresses();
            this.populateFormFields();
        }
    };

    // Use jQuery to figure out what page we are on.  the body will contain the class matched by name in the
    // view/adminhtml/layout folder
    if ($('body.customer-index-edit').length > 0) {
        return Abstract.extend(theArray);
    }

});
CarComp
источник

Ответы:

3

Вы можете использовать пользовательскую привязку afterRender, предоставляемую ядром Magento.

Вот пример из ядра. Шаблон добавляет, afterRender="setStickyNode"который вызывает функцию setStickyNode в ViewModel.

Вот еще один базовый пример:

Мой шаблон:

<div afterRender="doSomething" id="example1">
    <h1>This is a test</h1>
</div>

Моя ViewModel:

return {
    doSomething: function () {
        // Code that will run after id="example1" element is rendered on the page.
    }
}
dmatthew
источник