ACTUALIZACIÓN : puede acceder a los modelos de vista directamente. Si necesita activar el código para que se ejecute después de un render, use MutationObserver. Publicaré mi código tan pronto como tenga un buen ejemplo de trabajo.
Pregunta original: Tenemos muchos pedidos por teléfono. Estoy trabajando en un módulo que rellena automáticamente los datos en admin -> cliente -> crear nuevo desde nuestra solución CRM utilizando una llamada webapi / jsonp. De esta manera, los datos en magento no crean duplicados de datos que ya hemos almacenado en nuestra 'base de datos maestra'.
Una tarea que aún me queda por hacer es agregar la (s) dirección (es) del cliente. Al principio, esto parecía simple, hasta que me di cuenta de que knockoutjs + magentojs está representando que todo en el formulario del cliente me impide capturar elementos con plantilla. Me está costando mucho tiempo intentar capturar los conjuntos de campos (elementos de entrada) después de eliminar todas las direcciones mediante programación y crear otras nuevas.
Si se pregunta por qué debería hacer eso, parte de mi código aparece y dice "HEY, ESTA PERSONA EXISTE YA. ¿QUIERES USARLA?" y elimina todo lo que ya ha escrito y lo reemplaza con la información correcta. Entonces el centro de llamadas lo valida, yadda yadda.
Compartiré el código que tengo hasta ahora, pero no funciona del todo bien. Para su información, esto extiende el resumen para detectar el evento 'onUpdate'. No me engañes por intentar acceder a la colección dentro de un elemento de la colección. No puedo encontrar una mejor manera de captar el evento onUpdate y aún mirar todos los campos.
También entiendo completamente lo que está mal, simplemente no tengo idea de cómo solucionarlo. Lo que está mal es que supuse que los elementos generados por la llamada .activate () estarían disponibles de inmediato en lo siguiente
document.getElementsByClassName ('admin__fieldset')
Esto es simplemente una lógica incorrecta. Idealmente, me ENCANTARÍA poder extraer el contenido del conjunto de campos sin tener que recurrir a este truco de interfaz de usuario, luego, una vez que tenga todo configurado, solo ríndalo.
No quiero recurrir a los hacks de jQuery para ver actualizaciones de 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);
}
});
fuente
Respuestas:
Puede utilizar el enlace personalizado afterRender proporcionado por el núcleo de Magento.
Aquí hay un ejemplo del núcleo. La plantilla agrega
afterRender="setStickyNode"
qué llamadas a la función setStickyNode en ViewModel.Aquí hay otro ejemplo básico:
Mi plantilla:
Mi modelo de vista:
fuente