为什么不建议将 $rootScope 与函数一起使用? [英] Why using $rootScope with functions is not recommended?

查看:21
本文介绍了为什么不建议将 $rootScope 与函数一起使用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在研究 Angularjs 的 FEQ 时,我看到了下面的文章:

While am looking into the FEQs of Angularjs I've seen below article:

$rootScope 存在,但可用于作恶

Angular 中的作用域形成了一个层次结构,原型上继承自树顶部的根作用域.通常这可以忽略,因为大多数视图都有自己的控制器,因此也有自己的作用域.

Scopes in Angular form a hierarchy, prototypally inheriting from a root scope at the top of the tree. Usually this can be ignored, since most views have a controller, and therefore a scope, of their own.

有时您希望将一些数据全局化到整个应用程序中.对于这些,您可以像任何其他范围一样注入 $rootScope 并在其上设置值.由于作用域继承自根作用域,因此这些值将可用于附加到诸如 ng-show 之类的指令的表达式,就像本地 $scope 上的值一样.

Occasionally there are pieces of data that you want to make global to the whole app. For these, you can inject $rootScope and set values on it like any other scope. Since the scopes inherit from the root scope, these values will be available to the expressions attached to directives like ng-show just like values on your local $scope.

当然,全局状态很糟糕,您应该谨慎使用 $rootScope,就像您(希望)在任何语言中与全局变量一起使用一样.特别是,不要将它用于代码,仅用于数据.如果您想将一个函数放在 $rootScope 上,那么最好将它放在一个可以注入到需要的地方并且更容易测试的服务中.

Of course, global state sucks and you should use $rootScope sparingly, like you would (hopefully) use with global variables in any language. In particular, don't use it for code, only data. If you're tempted to put a function on $rootScope, it's almost always better to put it in a service that can be injected where it's needed, and more easily tested.

相反,不要创建服务的唯一目的是存储和返回数据位.

Conversely, don't create a service whose only purpose in life is to store and return bits of data.

—AngularJS常见问题 - $rootScope 存在,但它可以用于邪恶

所以我的疑问是为什么不建议将 $rootScope 用于函数作为全局函数?是否有任何性能问题?

推荐答案

我以前回答过这个问题,但你能提出这些问题很好.

I've answered this in the past, but it's good that you're asking these questions.

$rootScope 存在,但它可以用于 Angular 形式的层次结构中的邪恶作用域,原型是从树顶部的根作用域继承的.通常这可以忽略,因为大多数视图都有自己的控制器,因此也有自己的作用域.

$rootScope exists, but it can be used for evil Scopes in Angular form a hierarchy, prototypally inheriting from a root scope at the top of the tree. Usually this can be ignored, since most views have a controller, and therefore a scope, of their own.

非隔离作用域是分层的,但大多数开发人员应该使用具有隔离作用域的指令.AngularJS 范围的分层性质是 Angular 应用程序中许多错误的根源.这是一个我喜欢称之为范围出血的问题,其中范围属性在 DOM 树的某处被神奇地修改了,而你不知道为什么.

Non-isolated scopes are hierarchical, but most developers should be using directives that have isolated scopes. The very hierarchical nature of AngularJS's scope is the source of many bugs in angular apps. It's a problem I like to call scope bleeding where a scope property is modified magically somewhere in the DOM tree and you don't know why.

Angular 的默认行为是针对固有范围的,这使得一个控制器很容易更新由另一个控制器管理的内容,依此类推.这就是创建源代码之间的意大利面条式连接的方式.使维护该代码变得非常困难.

Angular's default behavior is to inherent scopes and this makes it tempting for one controller to update something managed by another controller, so on, and so on. This is how spaghetti connections between source code is created. Making it very difficult to maintain that code.

有时您希望将一些数据全局化到整个应用程序中.对于这些,您可以像任何其他范围一样注入 $rootScope 并在其上设置值.

Occasionally there are pieces of data that you want to make global to the whole app. For these, you can inject $rootScope and set values on it like any other scope.

不,那不正确.AngularJS 允许你定义诸如常量、值和服务之类的东西.这些东西可以注入到路由、控制器和指令中.这就是你如何让你的应用程序全局访问东西,如果你想让你的控制器或指令可测试,你将如何做到这一点.单元测试编写者不知道指令或控制器所依赖的 $rootScope 中应该有哪些属性.他们必须假设 $rootScope 没有发生变异以提供服务或数据.

No that's not correct. AngularJS allows you to define things like constants, values, and services. These are things that can be injected into routes, controllers and directives. That is how you make things accessible globally to your app, and this how you do it if you want to make your controllers or directives testable. A unit test writer doesn't know what properties should be in the $rootScope that a directive or controller depends upon. They have to assume that the $rootScope has not mutated to provide a service or data.

当然,全局状态很糟糕,您应该谨慎使用 $rootScope,就像您(希望)在任何语言中与全局变量一起使用一样.

Of course, global state sucks and you should use $rootScope sparingly, like you would (hopefully) use with global variables in any language.

问题不在于 $rootScope,而在于人们用它做什么.许多应用程序将当前用户、身份验证令牌和会话数据添加到 rootScope 中.这最终在模板中被大量使用(如果用户登录则显示 X,否则显示 Y).问题是 HTML 不传达范围层次结构.因此,当您看到 {{user.firstname + ' ' + user.lastname}} 时,您不知道变量 user 来自哪里.第二个问题是子作用域可以隐藏根属性.与前面的示例一样,如果指令执行此操作 scope.user = 'bla bla bla'.它没有替换 rootScope 上的值.它隐藏了它.现在你在模板中得到了一些奇怪的意想不到的东西,你不知道为什么变量 user 发生了变化.

The problem isn't $rootScope but what people are doing with it. Many apps add the current user, the auth tokens, and the session data into the rootScope. This ends up getting used heavily in templates (shows X if user logged in otherwise show Y). The problem is that the HTML doesn't communicate scope hierarchy. So when you see {{user.firstname + ' ' + user.lastname}} you have no idea where the variable user came from. The second problem is child scopes can shadow root properties. As in the previous example if a directive does this scope.user = 'bla bla bla'. It hasn't replaced the value on the rootScope. It's hidden it. Now you get some strange unexpected things in the templates, and you don't know why the variable user has changed.

相反,不要创建服务的唯一目的是存储和返回数据位.

Conversely, don't create a service whose only purpose in life is to store and return bits of data.

Angular 的 $cacheFactory$templateCache 是仅用于存储数据的服务示例.我认为作者试图鼓励在 Angular 的模块中使用常量和值,但这并不是一个好的描述.

Angular's $cacheFactory and $templateCache are examples of services that exist only too store data. I think the author was trying to encourage the use of constants and values in Angular's modules, but that's not a good description to do that.

所以我的疑问是为什么不建议将 $rootScope 用于函数作为全局函数?是否有任何性能问题?

So My doubt is why $rootScope is not recommended for functions as a global function? Is there any performance issue?

$rootScope 是 angular.config(..) 期间唯一可用的范围.如果这是您唯一可以修改范围,则在这段时间内可以修改范围.例如;您可能需要在应用启动之前注入 API 密钥或 Google 分析变量.

The $rootScope is the only scope available during angular.config(..). It's during this time that the scope can be modified if this is the only time that you can do it. For example; you may need to inject an API key or Google anayltics variable before the app starts.

任何作用域上的函数通常是个坏主意.主要是因为范围中的所有内容都在模板上的表达式中被消化.功能帐篷隐藏繁重的操作.无法通过调用函数时读取 HTML 来判断模板的重量.我见过像 getHeight() 这样的作用域函数,其中函数本身执行了 3 级嵌套循环.每次 angular 消化观察者以查看它是否发生变化时,都必须调用该函数.您应该尽量保持模板干燥.

Functions on any scope are generally a bad idea. Mainly for the reason that everything in scopes is digested in expressions on the templates. Functions tent to hide heavy operations. It's impossible to tell how heavy a template is by reading the HTML when it calls a function. I've seen scope functions like getHeight() where the function itself performed 3 levels of nested loops. That function has to get called every time angular digests the watchers to see if it's changed. You should try to keep your templates as dry as possible.

这篇关于为什么不建议将 $rootScope 与函数一起使用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆