首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将$scopes存储在工厂中

将$scopes存储在工厂中
EN

Stack Overflow用户
提问于 2015-06-09 19:51:30
回答 3查看 301关注 0票数 3

我正在向一个不是我自己编写的Web应用程序中添加一些特性。我觉得不能添加一个滑动功能。

我在某个地方看到"$scope不能在工厂中访问“,但我设法在工厂中存储了由ng-重复创建的所有作用域。由于JavaScript按值传递,所以我可能没有“存储作用域”,但如果在工厂中设置作用域ng类,则可以清楚地看出两者之间的区别。我认为这是个好主意,因为穿越范围是一种痛苦。我是在淘金,还是在浪费速度和空间来存储海量的数据,这就是范围?

main.html

代码语言:javascript
复制
<div ng-controller="someCtrlWhichWasDeclaredALongTimeAgo">
    .
    .
    . 
    <div class="items-container"
         ui-sortable="sortableOptions"
         ng-model="selectedSession.items">
        <div ng-repeat="item in selectedSession.items"
             ng-controller="itemEditorCtrl"
             ng-class="{'item-last':$last}">
            <div ng-if="item._value !== undefined"
                 class="item inline-comment">
                <span class="handle"></span>
            </div>
            <div ng-if="item._value === undefined"
                 class="item"
                 ng-include="'/views/item-editor.html'"></div>
            </div>
        </div>

        <div class="stopper"></div>
    </div>
</div>

item-editor.html

代码语言:javascript
复制
<div item-editor
     swipe-function="swipeMe"
     ng-swipe-left="swipeLeft(item)" 
     ng-swipe-right="swipeRight(item)">
     ...
</div>

这将用我的魔法代码呈现一个列表。如果单击列表中的项目,它将展开到全屏。你应该可以从那里在物品之间滑动。

我不认为我需要发布更多的HTML来解释这个问题。我确实在$rootScope.$broadcast上成功地实现了滑动,但是如果我的列表中有100项呢?会不会随着越来越多的项目接收和处理信息而变慢呢?我宁愿在选择此会话时将所有作用域加载到一个工厂中,然后在取消选择会话时将其删除。它可能需要一些时间开始,但它不需要5分钟的滑动。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-06-09 20:04:14

“不能在工厂中访问$scope”

你几乎是对的。不能将$scope服务注入另一个服务。没有什么可以阻止您创建一个存储数据的服务,并将$scope作为数据放入其中。

,这是个坏主意。服务用于在组件之间共享数据。$scope用于与视图进行通信。把这个想象成香蕉和烤面包机。两者都有其目的,没有人会因为你使用其中一种或另一种而责怪你,但是使用一个服务来存储$scope就像在烤面包机里塞上香蕉一样。

每个使用$scope的组件都应该只关注它自己的作用域--没有其他的(有非常罕见的例外情况,但您不应该使用它们,除非您知道自己在做什么)。

相反,将数据放在服务中,然后将服务的数据放到范围中:

代码语言:javascript
复制
.controller('ExampleController', function($scope, myService) {
  $scope.names = myService.names;
});

更好的是,您可以查看使用语法

票数 0
EN

Stack Overflow用户

发布于 2015-06-09 20:07:00

你所做的一切都很好。您可以随意在应用程序周围传递作用域对象。记住他们代表的是什么。$scope对象是您与视图的接口。大多数情况下,您的服务与视图没有什么关系,最好是在控制器和指令之间共享数据。尽管如此,有几个例子表明,服务间接地影响视图是完全有意义的。例如,我们编写了一个纺纱服务,它允许旋转器指令向服务注册自己。

spinner指令将spinnerService注入其中,调用spinnerService.register函数并传递其隔离作用域,这样服务就可以跟踪它,并使用它切换旋转器的on和off。然后,我们的devs可以将服务注入到他们需要的任何地方,并在需要时隐藏/显示加载的纺丝器或旋转器组。

他们所说的"$scope不能在工厂中访问“的意思是,您不能在工厂中注入$scope$scope被绑定到DOM元素(控制器或隔离指令对其调用的元素),因此向工厂注入新的$scope没有多大意义,而且实际上是不可能的。您不能执行app.factory('myFactory', function ($scope) { ... });,但是您可以从控制器或指令中调用工厂/服务,并将作用域对象从那里传递给您在服务上提供的方法。

只要您知道自己在做什么,跟踪服务中的作用域就没有什么问题。人们会告诉您,您不能将您的范围传递到服务中,因为它是反模式的,但随后他们会建议将类似的内容放在您的指令/控制器中,然后将其传递给服务:

代码语言:javascript
复制
var api = {
  hideSpinner: function () {
    $scope.show = false;
  },
  showSpinner: function () {
    $scope.show = true;
  }
};

当然,您并不是直接将$scope对象传递给服务,但是如果参数是scope对象可能会卡在内存中而不会被垃圾收集,那么这个解决方案也没有帮助。您构建和传递的API对象带着它的JavaScript作用域链,将它定义的作用域中的所有变量都保存在内存中,包括控制器/指令的$scope。必须这样做,否则这些API方法就无法工作。您的$scope ,它是该组件的一种API,以这种方式使用它是可以的。

执行上述示例的一个更好的理由是,您的$scope对象可能包含您不需要/不想与服务共享的信息或函数。使用您想要向服务公开的内容创建一个小API对象是非常有意义的。然后,您的服务只能访问您希望它能够访问的东西,并且仍然可以影响控制器/指令$scope,但是只能以您传入的API对象所概述的方式访问。

票数 2
EN

Stack Overflow用户

发布于 2015-06-09 19:59:54

请远离在任何类型的全局存储中存储$scope对象。这包括$rootScope和。

由于角中的服务是单例的,如果任何服务都在跟踪$scope对象(在任何服务变量中),那么$scope可能永远得不到释放,并且存在内存泄漏的可能性。

而且,scope的概念与视图紧密联系在一起,不应该在该上下文之外使用。

也许您可以与您的实现共享一些代码,这样我们就可以提出更好的解决方案。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30741569

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档