角度方式'将存储状态添加到应用程序
The 'angular way' of adding stored state to an application
我们正在使用Angularjs开发一个单页电子学习应用程序,我们已经到了需要跟踪某些组件是否'可完成'以及是否完成的地步。
不幸的是,我几乎可以肯定我对Angularjs概念的理解是有缺陷的,所以在轻率地提出一些生硬的解决方案之前,我想知道实现这一目标的"角度方式"是什么。
我已经添加了一个自定义属性指令'eng-completable'到一个组件的html模板(一个弹出,显示在一个按钮点击)。我还可以添加一个(可能是虚假的)ng-model="completed"变量声明…(下面的第一行是相关的,其他行都很好)
<div eng-completable ng-model="completed" class="hidden popup {{component.popup.type}}" id="{{component.popup.name}}" data-replaces="{{component.popup.replaces}}">
<div ng-if="component.popup.type=='overlay'">
<div class="float-right button close-button">X</div>
</div>
<p class="heading">{{component.popup.heading}}</p>
<div class="popup-content">
<div ng-if="0" ng-repeat-start="(innerIndex, component) in component.popup.popup_components"></div>
<div ng-if="0" ng-repeat-start="(type, object) in component"></div>
<div ng-attr-id="{{'p' + pageId + '-s' + skey + '-c' + ckey + '-component-' + index + '-innerComponent-' + innerIndex}}" ng-switch="type">
<div ng-switch-when="image" eng-image></div>
<div ng-switch-when="paragraph" eng-paragraph></div>
</div>
<div ng-if="0" ng-repeat-end></div>
<div ng-if="0" ng-repeat-end></div>
</div>
</div>
我在app.js文件中添加了相应的指令:
app.directive('engCompletable', function() {
return {
restrict: 'A',
link: function(scope, element, attrs) {
scope.completed = false;
console.log("completable attribute encountered and triggered: scope.completed = "+scope.completed);
}
}
});
然后呢?我如何在"全局"意义上访问完成的变量?事实上,下一步似乎并不明显,这表明我已经走错了。
在angular应用中存储和跟踪多个补全变量(在多个作用域?)的最好方法是什么?
编辑
我想我可能需要包括更多的细节来真正揭示我的问题:
假设我能够在每个engi -completable指令的作用域中添加一个'completable'属性,当用户点击一个按钮组件时,它会触发一个相应的弹出组件(通过对DOM元素的id引用),我如何引用弹出组件的角作用域来改变'completable'属性?
我知道这个问题的框架可能是有缺陷的,但是,如果是的话,我想知道在angular中,什么是"正确"的方法。
谢谢。
订阅事件是在控制器之间共享数据的好方法。下面是一个示例,向另一个控制器共享一个注释已加载完成,'controller1'将跟踪所有已加载的注释。
等待查看谁被加载的控制器示例:
angular.module('app').controller('controller1', ['$scope', '$rootScope', function controller1($scope, $rootScope) {
var unsubscribe = $rootScope.$on('comment:loaded', commentLoaded);
$scope.$on('$destroy', function removeBindings() {
unsubscribe();
});
var commentIdsLoaded = {};
function commentLoaded(event, comment) {
commentIdsLoaded[comment.id] = true;
}
});
通知注释加载的控制器
angular.module('app').controller('controller2', ['$scope', '$rootScope', function controller2($scope, $rootScope) {
function commentFinishedLoading(comment) {
$rootScope.$emit('comment:loaded', comment);
}
});
此解决方案允许您管理注释,而无需将它们存储在$rootScope中,并且仅将数据存储在需要它的模型中。如果您更改页面,它还可以防止存储这些数据的内存泄漏。
事件可能是在组件之间共享这种状态的最轻量级的方式,也是我开始处理这类问题的方式。
有了更多的组件间交互,事件可能会变得麻烦且容易出错。当有很多发射器和/或侦听器时,您需要确保正确的组件正在处理正确的消息。实际上,您还在每个相关组件中复制状态,这使得很容易出现不同步问题。
主要的替代方案是使用一个共享服务来管理共享状态,这允许没有状态复制。服务是单例的,因此您可能认为它们不能很好地管理多个唯一的状态,但是它们可以很好地保存状态的映射(或数组),并监视更改。
一个共享服务的方法看起来像这样:
// Shared service
angular.module('app').service('completables', function(){
// A map of, perhaps { exerciseId : isCompleted }
var _states = {};
// You could put getters and setters on here to be more explicit
return { 'states': _states }
});
// Some high-level controller
angular.module('app').controller('highLevel', ['completables', function(completables){
$scope.completables = completables;
$scope.$watch('completeables.states', function(oldStates, newStates){
// Do something whenever ANY states change
});
});
// Low-level directives
app.directive('engCompletable', ['completables', function(completables){
return {
scope: { exercise: '=' },
link: function(scope, element, attrs) {
// Set initial (shared) state
completeables.state[scope.exercise.id] = false;
// Triggered by user interaction
scope.completeExercise = function(){
completeables.state[scope.exercise.id] = true;
};
// You could also watch for external changes to just this exercise
scope.completables = completeables;
scope.$watch('completables.' + [scope.exercise.id], function(oldState, newState){
// Do something when changed externally
});
}
}
}]);
共享服务会产生更多的观察者,因此请记住这一点。但是它将状态保持在一个地方——非常适合于保持同步——并且感觉更健壮一些。
- Ember.js-接口状态应该存储在哪里
- 在 React JS 中,什么时候应该使用存储而不是直接操作视图的状态
- 在 Redux 状态下存储具有原型函数的对象
- React + Flux:将初始状态引入存储
- 存储在HTML5存储中的引导崩溃的当前状态
- 通量:多个容器具有相同的存储,不同的状态
- 在 Javascript 中存储对象的当前状态的最佳实践是什么?
- 当存储状态更改时,React 组件不会更新
- 如何重置 Redux 存储的状态
- 使用会话存储复选框的状态
- 将对象存储在 React 组件的状态中
- 如何对 Flux 存储中的状态变量强制执行隐私
- 使用本地存储维护复选框的选中状态
- 将压缩状态存储在“#”之后的 URL 中
- 捕获D3库创建的可视化并将状态存储在DB中
- Ajax和后退按钮.哈希更改,但上一页的状态存储在哪里
- 为什么不将redux存储状态存储在本地组件状态中呢?
- 关于多功能应用的状态存储和通量存储的问题
- 如何将复选框的先前状态存储在多个手风琴中
- IE9状态/存储选择选项将不会追加