gpt4 book ai didi

javascript - 一旦实例引用丢失,则编辑或删除BreezeJS EntityManager

转载 作者:行者123 更新时间:2023-12-03 12:11:50 25 4
gpt4 key购买 nike

我正在使用BreezeJS和AngularJS构建具有SPA结构的CRM应用程序,并且正在利用动态生成的选项卡式环境来显示我将在此处作为模块提及的内容。当用户单击侧面菜单项时,将创建一个新的选项卡,并将HTML模板(aka模块)加载到新的内容区域中。有些模块类型一次只能打开一次(一个帐户网格),而其他模块类型(例如“帐户编辑器”模块)可以打开多次。这样,用户可以在一天中的任何给定时间修改多个帐户,但始终可以从单个“帐户”网格实例进行修改。

到目前为止,我有一个用于“帐户编辑器”模块的工作系统,其中,我创建了具有适当配置参数(服务名称,保存选项等)的主控Breeze EntityManager,然后在每次使用新的“帐户编辑器”时都对其进行复制使用masterManager.createEmptyCopy()创建(根据http://www.breezejs.com/documentation/multiple-managers#CreateMultipleManagers中概述的代码):

var serviceName = "/breeze/accounts";

var ds = new breeze.DataService({
serviceName: serviceName,
hasServerMetadata: true
});

var masterManager = new breeze.EntityManager({
dataService: ds,
saveOptions: new breeze.SaveOptions({ allowConcurrentSaves: false })
});

function createManagerCopy() {
// same configuration as master; no entities in cache.
var sandboxManager = masterManager.createEmptyCopy();
return sandboxManager;
}


然后,我通过传入复制的 EntityQuery和实体 EntityManager来调用 Id (key),以便获得适当的帐户并使用Breeze的所有优点填充每个打开的编辑器。

function queryAccountByKey(mgr, key) {
var keyPredicate = breeze.Predicate.create('id', 'eq', key);
var query = new breeze.EntityQuery('AccountsBase')
.expand('ContactsBase')
.where(keyPredicate);

var promise = mgr.executeQuery(query)
.catch(queryFailed);

return promise;

function queryFailed(error) {
console.log('Query Account by Id Failed', error);
return $q.reject(error); // so downstream promise users know it failed
}
}


与其他打开的编辑器及其各自的实体管理器似乎没有任何冲突,因此,只要在模块的Angular EntityManager中维护复制的 scope,就可以了。以这种方式进行编辑和保存是一件轻而易举的事! :P(对不起)

我遇到的问题是,当我切换到另一个Angular route(例如登录屏幕),然后又回到主屏幕时。由于每个选项卡式模块的复杂性,必须从存储的设置中重新加载我在进行路由之前打开的任何“帐户编辑器”模块(即使布局存储在缓存中)。但是,有两个Breeze实体经理在处理该帐户。效果是,保存单个帐户编辑器的更改现在将提交两次(或者无论您离开首页还是从首页返回很多次)。

我要弄清楚的是,一旦我导航回主页布局并且原始实例引用(在我的情况下)丢失了,那么如何从客户端访问特定的 EntityManager实例。换句话说,是否可以查询 EntityManager集合以重用或删除实例?如果我可以通过名称或其他ID来获取管理器实例,则只需将其重新分配到我的作用域中,而无需删除并重新创建它。

如果确实需要删除 EntityManager,那么我找不到任何地方来描述实现类似 destroy()方法的东西……只是一个 clear()方法,该方法仅清除实体而不会删除< cc>从客户端。当然,如果我要解决所有这些错误,请提出更好的方法。希望我已经足够清楚地解释了事情,以便有人可以提出可能的解决方案。



因此,多亏了PW Kad的回答,通过在初始化时将它们添加到$ rootScope上的空对象集合中,我能够重用实体管理器,而不是删除并重新创建它们。以上概述)。这样可以访问整个Angular应用程序,而不会污染全局名称空间。我已经实现了与每个选项卡关联的唯一 EntityManager-从而与内容区域中的模块关联-因此我附加了该ID以创建名称(例如 createEmptyCopy())以存储在 ID对象中。以后,我可以使用每个帐户编辑器的Angular 'EM_' + instanceId中找到的ID来检索 $rootScope.entityManagers中的 EntityManager实例。

这是新的代码:

// NEW: Add an 'entityManagers' object to the $rootScope of my main app module
angular.module('app', [])
.run(['$rootScope', function($rootScope) {
$rootScope.entityManagers = {};
$rootScope.entityManagers.count = 0;
}]);

// In the dataServices factory for the main app module
var serviceName = "/breeze/accounts";

var ds = new breeze.DataService({
serviceName: serviceName,
hasServerMetadata: true
});

var masterManager = new breeze.EntityManager({
dataService: ds,
saveOptions: new breeze.SaveOptions({ allowConcurrentSaves: false })
});

function createManager(instanceId) {
// make a copy of the above EntityManager (with no cached entities)
var sandboxManager = masterManager.createEmptyCopy();

// NEW: Save the EntityManager instance to the $rootScope
$rootScope.entityManagers['EM_' + instanceId] = sandboxManager;
$rootScope.entityManagers.count++;

return sandboxManager;
}

// In the event that you want to delete the EntityManager from the $rootScope
function deleteManager(instanceId) {
var manager = $rootScope.entityManagers['EM_' + instanceId];
manager.clear();
delete $rootScope.entityManagers['EM_' + instanceId];
$rootScope.entityManagers.count--;
}

// And lastly, inside any Angular controller
$scope.instanceId = '1234'; // Dynamically-assigned at runtime

$scope.init = function() {
var manager = $rootScope.entityManagers['EM_' + $scope.instanceId];
if (manager === undefined) {
$scope.entityManager =
entityManagerService.createManager($scope.instanceId);
} else {
$scope.entityManager = manager;
}
}

$scope.getEntityById = function(id){
//use $scope.entityManager here to query database via Breeze
}


虽然我仍然想知道BreezeJS在哪里保存其 $rootScope集合,但我有一个有效的解决方案。希望对您有所帮助!

最佳答案

每次更改页面时都要重新实例化一个新的实体管理器,这似乎是一个糟糕的设计选择,实际上,您正在丢失高速缓存机制并在页面之间共享实体,但是如果必须这样做,则始终可以使用-

var manager = {};

manager = manager ? manager.clear() : new breeze.EntityManager();


要么

manager = manager ? (function () { delete manager; return new breeze.EntityManager(); })() : new breeze.EntityManager();


或其他许多方式

我建议尽管不要这样做,而只是做这样的事情-

var manager = {};

// Some route activation logic
if (!manager) {
manager = new breeze.EntityManager();
}


编辑

好吧,简短的答案是我不是100%确信全局名称空间中的微风对象如何引用实体管理器。我认为微风对象不会保留一组实体管理器,但是我可能是错的。我不明白为什么在实体管理器上调用delete不能正常工作,但这应该可以完成您想要做的事情-

在您的闭包之一或全局名称空间中的某个位置创建一个名为entityManagers的对象。范例-

window.entityManagers = {};
window.entityManagers.count = 0;


然后在创建到该名称空间的管理器上添加标签。仅给出一些伪代码,可能会有更动态的方法来执行此操作-

window.entityManagers.createNewManager = function (name) {
window.entityManagers[name] = new breeze.EntityManager();
}


window.entityManagers.createNewManager('ManagerNumber1');


然后,当您要处置特定实例时,只需将其清除然后删除即可。通过变量引用获取所需的实例,或者由于某种疯狂的原因而无法做到这一点,只需将其从受影响的实体中取出即可-

window.entityManagers.deleteManager = function (name) {
window.entityManagers[name].clear();
delete window.entityManagers[name];
}

window.entityManagers.deleteManager('ManagerNumber1');


出于所有意图和目的,只要在其他模块/控制器/中没有其他对管理器实例的引用,应该从世界上删除entityManager。我仍然不完全理解用例,因此请带一点盐。

关于javascript - 一旦实例引用丢失,则编辑或删除BreezeJS EntityManager,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24933951/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com