我的应用程序需要UX中的复杂步骤才能到达其中的一些状态。这使得开发/测试周期非常麻烦,因为简单的布局更改必须在各种状态下进行可视化验证。
所以,我正在考虑以这样的方式获取正在运行的应用程序的转储/快照(即window.angular,或者也许是$ rootscope)的实用性,以便我可以快速从该快照恢复,运行一个$ rootscope。$ digest()和et voila。
有关如何实现这一目标的任何建议?
我不希望恢复的快照能够正常运行,例如,它不需要有活跃的观察者或广播订阅。它只需忠实地呈现视觉检查视图。
- 编辑 -
我开始认为这无法完成。
我已经意识到,从现在开始我的所有Angular项目都将拥有一个名为VmStateService的服务,基本上,影响渲染视图的每一项VM数据都必须生效在这个单一服务中,它被注入每个控制器。这样我只有一个干净的对象(它没有任何功能),我可以转储到字符串,或保存到本地存储,然后恢复以创建我想要测试的任何视图。
我想很不幸的是,每个人都通过$ scope.foo =" bar"来学习AngularJS,然后花费其余的职业生涯来实现创造的混乱。
答案 0 :(得分:1)
简单地使用JSON.Stringify
的问题在于它不会正确捕获函数,也不会捕获合法的undefined
值或循环引用。你可以用作起点的东西是Node JS的util.inspect()
:
https://github.com/nodejs/node/blob/master/lib/util.js#L87
这已经完成了一半的工作 - 读取对象,正确格式化,管理所有细微差别。还读取函数和循环引用。你必须做另外一半的工作来翻译它,但你应该能够。
(这些是Node的许可条款 - 对于Node本身的MIT许可,其他库可能稍微严格(但不是那么多)):
https://raw.githubusercontent.com/nodejs/node/master/LICENSE
答案 1 :(得分:1)
修改强>
首先,如果您有兴趣做的就是获取视觉检查的视图,为什么不这样做?
document.body.parentNode.innerHTML
但是,你可能想要更多,特别是如果你想捕获任何输入字段的值等,这些东西不是由DOM的静态HTML表示的。
要解决您的问题,您必须捕获所需的任何信息,以重新创建视图状态。在Angular中,这可能意味着:
除非您针对此功能规划应用程序架构,否则很难做到这一点。无论你如何分割它,你都需要进行一些重构。您还需要一个鼓励您可以快照的状态的体系结构,以便能够保存/恢复未来的开发。
听起来你可以从FLUX架构中受益。如果您不熟悉FLUX,我建议您查看at the flux website。
我已经在我的Enterprise Angular应用程序中实现了一个版本的FLUX,使用RxJS进行操作,并为商店提供服务(我只是将它们命名为<Feature>Store
,并通过{{1}注入它们})。
但是,Flux的实施可能会解决您正在寻找的问题,https://github.com/rackt/redux。 Redux是围绕React构建的,因此您需要构建从应用程序状态层到视图的桥梁(可以由Angular控制)。
Redux将应用程序状态保存在单个JS对象中,并跟踪该对象的每个原子更改。理论上,您可以立即保存/加载应用程序状态。
答案 2 :(得分:0)
这是一个天真的尝试。
用法:
serialize($rootScope)
获取根范围的字符串,序列化版本以及您将保存在文件,localStorage等中的子项
restore(myCopy, $rootScope)
将所有内容放回$ rootScope。 myCopy是之前复制方法返回的字符串序列化版本。
仅序列化自定义属性(而非函数)。任何以美元符号开头的东西都被视为私有角,不应该被混淆。如果您碰巧拥有以$
符号开头的自定义属性,则可以将该函数调整为仅忽略私有角色。
function serialize(target, source) {
source = source || {};
for (var key in target) {
if (!target.hasOwnProperty(key)) { continue; }
if (key[0] === '$' || key === 'constructor') continue;
if (typeof target[key] !== 'function') {
try {
source[key] = JSON.stringify( target[key] );
} catch(e) {}
}
}
if (target.$$nextSibling) {
source.$$nextSibling = {};
serialize(target.$$nextSibling, source.$$nextSibling);
}
if (target.$$childHead) {
source.$$childHead = {};
serialize(target.$$childHead, source.$$childHead);
}
return JSON.stringify(source);
}
function restore(copy, $rootScope) {
try {
copy = JSON.parse(copy);
} catch(e) {}
for (var key in copy) {
if (!copy.hasOwnProperty(key)) { continue; }
try {
$rootScope[key] = JSON.parse(copy[key]);
} catch(e) {
$rootScope[key] = copy[key];
}
}
if (copy.$$nextSibling) {
$rootScope.$$nextSibling = $rootScope.$$nextSibling || {};
restore(copy.$$nextSibling, $rootScope.$$nextSibling);
}
if (copy.$$childHead) {
$rootScope.$$childHead = $rootScope.$$childHead || {};
restore(copy.$$childHead, $rootScope.$$childHead);
}
}
// Create a $rootScope serialized copy that can be stored in local storage, etc
var copy = serialize($rootScope);
// Restore a serialized copy into $rootScope
restore(copy, $rootScope);
答案 3 :(得分:0)
我看到我的小项目可以部分满足您的要求。
https://github.com/vorachet/angular-state-manager
它还很年轻,设计目标是成为一个维护工具,以帮助Angular应用程序理解。我欢迎您研究您的详细要求,并尝试继续开发以解决您的问题。