Breeze не сохраняет правильное значение (установленное в коде) при сохранении во время события entityChanged.

У меня есть веб-приложение Breeze, Typescript, MVC 5.2, Knockout, Entity Framework. Я пытаюсь обновить значение объекта User, когда пользователь щелкает строку в сетке (kogrid). Значение (должно быть) сохранено в обработчике событий entityChanged, но в Fiddler я вижу, что значение свойства не изменилось, а для entityAspect.entityState установлено значение Modified (!) OriginalValuesMap имеет старый TenantId и является единственным значением в карта.

Я подписываюсь на событие изменения объекта следующим образом:

this.EntityManager.entityChanged.subscribe((data: breeze.EntityChangedEventArgs) => {
    if (data.entityAction == breeze.EntityAction.PropertyChange) {
                return this.EntityManager.saveChanges(<breeze.Entity[]> new Array(data.entity))
                    .fail((error) => alert("Failed. " + error));}

        });

Данные правильно поступают в обработчик событий. Выполняется вызов savechanges, но измененное значение (tenantId) не изменилось.

Обработчик события для rowclick выглядит следующим образом:

ViewModel).OnRowClick = (tenantId: KnockoutObservable<System.IGuid>, viewModel: Imp.Scripts._TenantListViewModel) => {
        entityManager.fetchEntityByKey("User", viewModel.Settings().CurrentUser().UserId(), false)
        .then(entityKeyResult => {
            (<Imp.Classes.UserBreeze>entityKeyResult.entity).CurrentTenantId(tenantId());
            //entityManager.saveChanges(<breeze.Entity[]> new Array(entityKeyResult.entity));
         })
        .fail((error)=> alert("Error setting current tenant. " + error));});

Когда я отключаю подписку entityChanged и включаю строку комментария entityManager.saveChanges.... объект сохраняется правильно. Если раскомментировать строку, но оставить подписку, то не работает.

Как я могу автоматически сохранить измененную сущность после ее изменения?

РЕДАКТИРОВАТЬ: Обходной путь заключается в временном отключении обработчика событий entityChanged перед изменением значения CurrentTenantId для текущего пользователя, сохранении объекта вручную и повторной подписке на событие entityChanged. Но этот раствор пахнет.


person RHAD    schedule 19.07.2014    source источник


Ответы (1)


Несколько предложений:

  1. Рассмотрите возможность ограничения сохранения, если события propertychanged запускаются часто. Для этой цели в Knockout есть расширитель ограничения скорости.
  2. Вы также можете рассмотреть возможность использования плагина быстрого сохранения очередей, чтобы вам не нужно было беспокоиться о перекрывающихся вызовах сохранения.
  3. Чтобы устранить проблему с сохранением, попробуйте добавить следующий код непосредственно перед вызовом saveChanges:

if (data.entityAction === breeze.EntityAction.PropertyChange) { var pcArgs = <breeze.PropertyChangedEventArgs>data.args; console.log('Property Changed. PropertyName: ' + pcArgs.propertyName + '; Old Value: ' + (pcArgs.oldValue ? pcArgs.oldValue.toString() : 'null') + '; New Value: ' + (pcArgs.newValue ? pcArgs.newValue.toString() : 'null') + ';'); }

person Jeremy Danyow    schedule 23.07.2014
comment
Я изменил ваш код, чтобы показать тип сущности: свойство изменено. Имя свойства: Тип CurrentTenantEntity: UserPoco:#Imp.Persistent; Старое значение: [объект объекта]; Новое значение: [объект Объект]; Свойство изменено. Имя свойства: Тип CurrentTenantIdEntity: UserPoco:#Imp.Persistent; Старое значение: 534b1611-9f36-47b5-9e20-d959aa0d97eb; Новое значение: db626552-b8c9-4682-a8ea-5945a54152f0; SaveQueuing уже был включен, и я установил rateLimit на 500 мс: К сожалению проблема осталась - person RHAD; 24.07.2014
comment
это означает, что сохранение происходит до назначения CurrentTenantId, верно? что, если вы оберните строку saveChanges следующим образом: setTimeout(... сохранить код изменений..., 0); - person Jeremy Danyow; 24.07.2014
comment
Я не думаю, что это означает, что сохранение происходит до назначения CurrenTenantId. Код вызывается, поскольку CurrentTenantId назначается в обработчике событий OnRowClick. Тем не менее, SetTimeOut сделал свое дело!! СПАСИБО! Я не могу объяснить, почему тайм-аут, установленный на ноль, решает мою проблему. - person RHAD; 25.07.2014
comment
Я думаю, что происходит событие propertychanged, связанное со свойством CurrentTenantEntity, инициирующее сохранение, затем назначается свойство CurrentTenantId, запускающее второе событие propertychanged. Трюк settimeout позволяет назначить оба свойства до того, как будет вызвано сохранение. - person Jeremy Danyow; 26.07.2014