Our blazing fast Grid component built with pure JavaScript


Post by henrique »

I'm having problems with the models, with circular reference.

Of course, this shouldn't exist, but in the database model we have here, it happens.

With this is stack overflow in the model when it tries to take copy of the values from the fields.

Is there a specific setting or field to resolve this issue?


Post by mats »

Can you please provide a small runnable code example so we can debug this?


Post by henrique »

This is the test code I'm using.

When click on the button the error happens.

import Button from '../../lib/Core/widget/Button.js';
import TextField from '../../lib/Core/widget/TextField.js';
import Container from '../../lib/Core/widget/Container.js';
import Model from '../../lib/Core/data/Model.js';
import Store from '../../lib/Core/data/Store.js';

console.clear();

class Person extends Model 
{
    static get fields() 
    {
       return [{ name: "id", type: "string"},
               { name: "Order", type: "model" },
               { name: "Name", type: "string" }];
    }
}

class Order extends Model 
{
   static get fields() {
      return [
         { name: "id", type: "string"},
         { name: "Buyer", type: "model" },
         { name: "BuyerName", type: "string", dataSource: "Buyer.Name" },
      ];
   }
}

let rawPerson = {Name: "Um nome", id: "a"};

let rawPerson2 = {Name: "Outra pessoa", id: "b"};

let rawOrder = {id: "abc"};

let person = new Person(rawPerson);

let person2 = new Person(rawPerson2);

let order = new Order(rawOrder);

person.Order = order;
order.Buyer = person;

console.log("rawPerson", rawPerson);
console.log("rawOrder", rawOrder);
console.log("person", person);
console.log("order", order);

let store = new Store({
   data: [order],
   modelClass: Order
});

let orderIdField = new TextField({
   width: 200,
   label: "Order Id",
   icon: "b-fa b-fa-plug",
   style: "margin-right: .5em",
   name: "Id"
});

let personNameField = new TextField({
   width: 200,
   label: "Customer name",
   icon: "b-fa b-fa-plug",
   style: "margin-right: .5em",
   name: "BuyerName"
});

let button = new Button({
   text: "Button",
   onClick: function () {
      store.first.Buyer = person2;
   }
});

let myContainer = new Container({
   appendTo: document.body,
   items: [orderIdField, personNameField, button]
});

myContainer.record = store.first;

Post by Animal »

This appears to be a bug in the Core.data.field.ModelDataField class.

It needs the following override:

    isEqual(first, second) {
        return (first && second) && (second instanceof first.constructor) && second.id == first.id;
    }

Otherwise it uses ObjectHelper.equals which does a deep test and finds the circularity (records are linked to their owning Stores, and of course Stores maintain references to all their records)

Here's a ticket to track: https://github.com/bryntum/support/issues/3855


Post by Maxim Gorkovsky »

Override class won't help here because method doesn't exist on the ModelDataField class. It is inherited from prototype and Override will replace method on the DataField prototype. See related issue: https://github.com/bryntum/support/issues/1756

To apply this override you can add method directly to the certain prototype:

import ModelDataField from '../../lib/Core/data/field/ModelDataField.js';

ModelDataField.prototype.isEqual = function(first, second) {
    return (first && second) && (second instanceof first.constructor) && second.id == first.id;
};

Post Reply