adminhtmlでknockoutjsレンダリング後にコードをトリガーして実行する方法


11

更新:ビューモデルに直接アクセスできます。レンダリング後に実行するコードをトリガーする必要がある場合は、MutationObserverを使用します。良い例ができたらすぐにコードを投稿します。

元の質問: 電話での注文がたくさんあります。私は、admin-> customer-> webapi / jsonp呼び出しを使用してCRMソリューションから新規作成するデータを自動入力するモジュールに取り組んでいます。このようにして、magentoのデータは、すでに「マスターデータベース」に保存したデータの複製を作成しません。

私がまだやらなければならない1つのタスクは、お客様の住所を追加することです。これは、kockoutjs + magentojsが顧客フォームのすべてをレンダリングしていることが、テンプレート化された要素のキャプチャを妨げていることに気づくまで、最初は簡単に思えました。プログラムですべてのアドレスを削除し、新しいアドレスを作成した後、フィールドセット(入力要素)をキャプチャしようとするのにかなり時間がかかっています。

なぜ私がそうするのかと思うと、私のコードの一部がポップアップ表示され、「こんにちは、この人物は既に存在します。それらを使用しますか?」すでに入力したものはすべて削除され、正しい情報に置き換えられます。次に、コールセンターがそれを検証します、yadda yadda。

ここまでのコードを共有しますが、正しく機能しません。ちなみに、これは「onUpdate」イベントをキャッチするためにAbstractを拡張しています。コレクションアイテム内のコレクションへのアクセスを試みたとして、私を非難しないでください。onUpdateイベントをキャッチし、すべてのフィールドを確認するためのより良い方法を思いつくことはできません。

私はまた、何が悪いのかを完全に理解しています。どうすればそれを回避できるのかわかりません。何が問題なのか、私は.activate()呼び出しによって生成された要素が以下ですぐに利用可能になると想定

document.getElementsByClassName( 'admin__fieldset')

これは間違ったロジックです。理想的には、このUIのトリックに頼ることなくフィールドセットのコンテンツをプルできるようにして、すべてを設定したらレンダリングするだけです。

私は、domの更新を監視するためにjQueryハックに頼りたくありません。

// 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);
    }

});

回答:


3

Magentoコアによって提供されるafterRenderカスタムバインディングを使用できます。

これはコアのです。テンプレートは、ViewModelでsetStickyNode関数afterRender="setStickyNode"を呼び出すを追加します。

次に、別の基本的な例を示します。

私のテンプレート:

<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.
    }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.