Перейти к содержанию

ModelSource#

Класс для работы с моделями, создает источник данных для объекта типа Модель.

Конструктор#

параметр тип описание
model object объект описания модели
options object дополнительные опции
options.db object имя профиля БД. По умолчанию берется значение из настройки applications.data.db в конфигурационном файле. Дополнительные профили указываются в applications.data.dbProfiles.
Пример создания экземпляра ModelSource:
1
2
3
    import { ModelSource } from 'ecosoft-lexema8'
    import model from './test.model.json'
    const source = new ModelSource(model)

Методы#

load#

Загружает данные модели

параметр тип описание
args object объект со свойсвами
args.VCode object значение первичного ключа для загрузки конкретного экземпляра модели (результат загрузки - объект). Если не передан, загружается коллекция экземпляров модели (результат загрузки - массив)
args.BDate Date задает начальную дату (условие >=) для фильрации по расчетной дате
args.EDate Date задает конечную дату (условие <=) для фильрации по расчетной дате
args.TopCount number задает ограничение на количество загружаымых строк
args.RowsOffset number задает смещение, которое позволяет пропустить указанное количество найденных строк
args.order [string], [object] задает сортировку по указанным колонкам. По умолчания указанные колонки сортируются по возрастанию. Для сортировки по убывания необходимо передать объект со свойствами: property - имя колонки; desc - если true, то включает сортировку по убыванию.
args.filter object задает фильтр по колонкам (доступные операторы см. ниже)
args.fields [string] массив свойств и дочерних коллекций модели, которые нужно загружать при частичной загрузке, подробнее
args.lock boolean флаг, означающий, что загрузка экземпляра модели должна сопровождаться попыткой его блокировки
isAsync boolean флаг, при котором отправленный запрос будет асинхронным. По умолчанию - true
Примеры
1
2
3
4
5
6
7
    import { ModelSource } from 'ecosoft-lexema8'
    import Contractor from './contractor.model.json'
    ...
    const modelSource = new ModelSource(Contractor);
    modelSource.load({ VCode: 123 }).done(data => {
      console.log(data);
    });
1
2
3
4
5
6
7
    import { ModelSource } from 'ecosoft-lexema8'
    import Contractor from './contractor.model.json'
    ...
    const modelSource = new ModelSource(Contractor);
    modelSource.load().done(data => {
      console.log(data);
    });
1
2
3
4
5
6
7
    import { ModelSource } from 'ecosoft-lexema8'
    import Contractor from './contractor.model.json'
    ...
    const modelSource = new ModelSource(Contractor);
    modelSource.load({ VCode: 123, lock: true }).done((data, lock) => {
      console.log(data, lock);
    });
    import { ModelSource } from 'ecosoft-lexema8'
    import Contractor from './contractor.model.json'
    ...
    const modelSource = new ModelSource(Contractor);
    modelSource.load({ VCode: 26 }) // если передан VCode, то грузиться объект, иначе массив
    modelSource.load({ BDate: new Date(2018, 0, 1), EDate: new Date(2019, 11, 31, 23, 59, 59, 999) })
    modelSource.load({ TopCount: 2 })
    modelSource.load({ RowsOffset: 2 })
    modelSource.load({ TopCount: 2, RowsOffset: 2, order: ['VCode'] })
    modelSource.load({ TopCount: 2, RowsOffset: 2, order: ['City.VCode'] }) // сортировка по коду справочника
    modelSource.load({ TopCount: 2, RowsOffset: 2, order: [{ property: 'City.VCode', desc: true }] }) // сортировка по коду справочника по убыванию
    modelSource.load({ fields: ['Name', 'City.Name', '[Detail].City'] })
    modelSource.load({ filter: { VCode: 26 } })
    modelSource.load({ filter: { Name: { $not: null } } })
    modelSource.load({ filter: { Name: { $not: null }, City: { $not: null } } })
    modelSource.load({ filter: { $or: [{ Name: { $not: null } }, { City: { $not: null } }] } })
    modelSource.load({ filter: { 'City.CDate': { $gt: new Date(2020, 0, 1) } } })

Частичная загрузка модели#

Метод load поддерживает частичную загрузку данных. Для этого нужно в объекте args передать свойство fields - массив свойств для загрузки. Если field был передан, то данный функционал работает по принципу белого списка - загружаются только те свойства, что были указаны. Поддерживается следующий формат передачи данных:

  • Field - загрузка поля Field.
  • ObjectField.Field - для справочной колонки ObjectField загрузить поле Field.
  • [Detail] - загрузка дочерней коллекции.
  • [Detail].Field - загрузка поля Field из дочерней коллекции Detail.

Примечания

  • Данное свойство не расширяет базовое ограничение на вложенность элементов модели.
  • Свойства, соответсвующие primaryKeyProperty и foreignKeyProperty (по умолчанию VCode и PCode соотвественно) моделей загружаются всегда, они требуются для связки загружаемых данных.
Пример
const VCode = 1
const modelSource = new ModelSource(model)
const fields = [
  'Name', 
  'ObjectField.Name', 
  '[Detail].Name'
]
modelSource.load({ VCode, fields }).done(data => {
  console.log(data);
})
{
  "VCode": "2",
  "Name": "second",
  "ObjectField": {
    "VCode": "1",
    "Name": "first"
  },
  "Detail": [
    {
      "VCode": "5",
      "Name": "fifth",
      "PCode": "2"
    },
    {
      "VCode": "3",
      "Name": "third",
      "PCode": "2"
    }
  ]
}

Операторы, доступные для фильтрации при загрузке данных#

Значени Расшифровка
$and 'AND'
$or 'OR'
$like 'LIKE' (для mssql), 'ILIKE' (для pg)
$ne '!='
$eq '='
$gt '>'
$gte '>='
$lt '<'
$lte '<='
$notLike 'NOT LIKE' (для mssql), 'NOT ILIKE' (для pg)'
$is 'IS NULL'
$not 'IS NOT NULL'

loadObservable#

Загружает данные модели с заданным кодом с учетом переданного фильтра по коду объекта или дате и конвертирует в observable.

Регистрирует изменения дочерних коллекций

Примеры
1
2
3
4
5
6
7
    import { ModelSource } from 'ecosoft-lexema8'
    import Contractor from './contractor.model.json'
    ...
    const modelSource = new ModelSource(Contractor);
    modelSource.loadObservable({ VCode: 123 }).then(data => {
      console.log(data);
    });

loadGroup#

Загружает данные модели с заданными группировками и агрегатами

Примеры
    const source = new ModelSource(Contractor)
    const aggregate = { VCode: ['$count'], Stage: ['$max', '$min'] }
    const group = ['CUser', 'Stage']
    const filter = { WDate: { $gt: '2016-01-01' }} 

    source.loadGroup({ aggregate, group, filter, RowsOffset: 0, TopCount: 100 }).done(function (data) {
        data.forEach( obj => {
            // вывод группировок
            console.log(obj.gr.CUser)
            console.log(obj.gr.Stage)
            // вывод значений агрегатов
            console.log(obj.ag.VCode.count)
            console.log(obj.ag.Stage.max)
            console.log(obj.ag.Stage.min)
        })
    });

save#

Сохраняет объект модели

параметр тип описание
data object объект со свойсвами
isNew boolean если true, то будет создан новый объект
Примеры
1
2
3
4
5
6
7
8
9
  const modelSource = new ModelSource(Contractor);

  // сохранение
  // .. краткая форма - изменение объекта, у которого значение первичного ключа = 326
  modelSource.save({ Name:'мояноваязаявка', VCode: 326 });

  // .. полная форма: пусть у нас есть загруженный объект модели - obj. меняем ему какие то свойства и сохраняем
  obj.Описание  = "test";
  modelSource.save(obj);

remove#

Удаляет переданный объект

параметр тип описание
args object объект модели
Примеры
  // удаление: краткая форма. Полная форма аналогично предыдущему примеру
  modelSource.remove({VCode:400});

genPrimaryKey#

Генерирует новое значение первичного ключа объекта

Примеры
1
2
3
4
5
6
    const modelSource = new ModelSource(Contractor);
    // создание объекта с заранее сгенерированным VCode:
    modelSource.genPrimaryKey().done(function(vcode){
        someObject.VCode = vcode;
        modelSource.save(someObject,true);//второй параметер показывает, что объект должен быть вставлен (insert,а не update) 
    });

createObject#

Создает документ

Примеры
1
2
3
4
5
6
    const model = new ModelSource(Contractor);

    $.when(model.createObject(), model.genPrimaryKey()
    ).done(function (obj, vcode) {
        obj.VCode(vcode[0]);
    });

Примеры#

Примеры
  const source = new ModelSource(Route);

  $.when(source.createObject(),
      source.genPrimaryKey()
  ).done(function (obj, vcode) {
      obj.VCode(vcode[0]);
      obj.DocType("docName");
      obj.Stages.push({StageNumber: 1, StageName: 'Тест A'},
          {StageNumber: 2, StageName: 'Тест B'});
      source.save(obj, true);
  });
  const routeSource = new ModelSource(Route),
  stageSource = new ModelSource(RouteStage);

  $.when(routeSource.createObject(),
      routeSource.genPrimaryKey(),
      stageSource.createObject(),
      stageSource.genPrimaryKey(),
      stageSource.createObject()
  ).done(function (route, routeVCode, stage1, stage1VCode, stage2) {
      route.VCode(routeVCode[0]);
      route.DocType("docName");
      stage1.VCode(stage1VCode[0]);
      stage1.StageName('stage 5');
      stage1.StageItems.push({StageUser: 'test1-test2'});
      route.Stages.push(stage1, stage2);
      routeSource.save(route, true);
  });
  const routeSource = new ModelSource(Route),
  stageSource = new ModelSource(RouteStage),
  stageItemSource = new ModelSource(StageItem);

  $.when(routeSource.createObject(),
      routeSource.genPrimaryKey(),
      stageSource.createObject(),
      stageSource.genPrimaryKey(),
      stageSource.createObject(),
      stageItemSource.createObject(),
      stageItemSource.genPrimaryKey()
  ).done(function (route,
      routeVCode,
      stage1,
      stage1VCode,
      stage2,
      stageItem,
      stageItemVCode
  ) {
      route.VCode(routeVCode[0]);
      route.DocType("docName");
      stageItem.VCode(stageItemVCode[0]);
      stageItem.StageUser('abcd');
      stageItem.DocflowMessages.push({
          Message: '123abc456'
      });
      stage1.VCode(stage1VCode[0]);
      stage1.StageName('stage 5');
      stage1.StageItems.push(stageItem);
      route.Stages.push(stage1, stage2);
      routeSource.save(route, true);
  });
  const routeSource = new ModelSource(Route),
  stageSource = new ModelSource(RouteStage),
  stageNames = ['test555', 'testAbc', 'klmn'];

  function createStagePromises(n) {
      return $.Deferred(function (result) {
          var stagePromises = [];

          for (var i = 0; i < n; i++) {
              stagePromises.push(stageSource.createObject());
          }

          $.when.apply($, stagePromises).then(function () {
              var stages = Array.prototype.slice.call(arguments, 0);
              result.resolve(stages);
          }, function (e) {
              result.reject(e);
          });
      });
  }

  $.when(routeSource.createObject(),
      routeSource.genPrimaryKey(),
      createStagePromises(stageNames.length)
  ).done(function (route, routeVCode, stages) {
      route.VCode(routeVCode[0]);
      route.DocType("docName");

      stages.forEach(function (stage, index) {
          stage.StageName(stageNames[index]);
          route.Stages.push(stage);
      });

      routeSource.save(route, true);
  });
  const routeSource = new ModelSource(Route),
  stageSource = new ModelSource(RouteStage),
  stageNames = ['test555', 'testAbc', 'klmn'];

  function createStagePromises(stageNames) {
      return $.Deferred(function (result) {
          var stagePromises = [];

          stageNames.forEach(function (name) {
              stagePromises.push(new Promise(function (resolve) {
                  var stage = stageSource.createObject();
                  stage.Description(name);
              resolve(stage);
          }));
        });

          $.when.apply($, stagePromises).then(function () {
              var stages = Array.prototype.slice.call(arguments, 0);
              result.resolve(stages);
          }, function (e) {
              result.reject(e);
          });
      });
  }

  $.when(routeSource.createObject(),
      routeSource.genPrimaryKey(),
      createStagePromises(stageNames)
  ).done(function (route, routeVCode, stages) {
      route.VCode(routeVCode[0]);
      route.DocType("docName");
      route.Stages.push.apply(route.Stages, stages);
      routeSource.save(route, true);
  });
1
2
3
4
5
6
  const source = new ModelSource(Contractor);
  source.loadObservable({ VCode: 337 }).done(function (obj) {  
      obj.Name('test');  
      obj.Detail()[0].Description('test');
      source.save(obj);
  });
1
2
3
4
5
  const source = new ModelSource(Contractor);
  source.loadObservable({ VCode: 337 }).done(function (obj) {   
      obj.Detail.splice(2, 1);
      source.save(obj);
  });