状态(和模型)存储在$ scope中
$ scope是Angular的数据存储对象。它类似于数据库。$ scope本身不是模型,但是您可以将模型存储在$ scope中。
每个$ scope都有一个父$ scope,一直到$ rootScope形成一个松散地镜像您的DOM的树结构。当您调用需要新$ scope的指令(例如ng-controller)时,将创建一个新的$ scope对象并将其添加到树中。
$ scope对象使用原型继承进行连接。这意味着,如果您在树中的较高级别添加模型,则所有较低级别的模型都可用。这是一个非常强大的功能,它使$ scope层次结构几乎对模板作者透明。
控制器初始化$ scope
控制器的目的是初始化$ scope。同一控制器可以在页面的不同部分初始化许多$ scope对象。实例化控制器,设置$ scope对象,然后退出。您可以使用同一控制器在页面的不同部分初始化许多$ scope。
对于图片库,您将有一个imageGallery控制器,然后使用ng-controller指令将其应用于要成为图库的DOM的每个部分。页面的该部分将获得其自己的$ scope,您可以使用它来存储selectedPhoto属性。
原型范围
$ scope一直使用普通的原型原型继承其父级,直到$ rootScope,因此您可以将对象存储在层次结构中有意义的任何位置。您将获得一棵$ scope对象树,该树与您当前的DOM大致相关。如果您的DOM更改,则会根据需要为您创建新的$ scope对象。
$ scope只是一个普通的JavaScript对象。创建多个$ scope对象比创建具有多个currentImage对象的数组没有浪费。这是组织代码的明智方式。
这样,Angular消除了JavaScript中经常出现的旧的“我在哪里存储数据”问题。这是我们从Angular获得的最大的生产力提升之一。
有全局数据(例如,一个userId)?将其存储在$ rootScope上。有本地数据(例如,在存在多个画廊实例的画廊中的currentImage)?将其存储在属于该库的$ scope对象上。
您可以在模板的正确部分自动使用$ scope。
角度模型很薄
来自我们强调胖模型和瘦控制器的Rails背景,我发现Angular的“几乎没有”模型令人惊讶。实际上,在模型中放置很多业务逻辑经常会导致一系列问题,正如我们有时会在Rails中的User模型中看到的那样,如果您不小心的话,它会一直增长到无法维护为止。
角度模型只是JavaScript对象或图元。
任何对象都可以是模型。模型通常是使用控制器中的JSON定义的,或者是通过服务器AJAX输入的。模型可以是JSON对象,也可以只是字符串,数组甚至是数字。
当然,没有什么可以阻止您向模型中添加其他功能并将它们存储在JSON对象中的,但是,这将移植到与Angular并不完全匹配的范例中。
角度对象通常是数据的存储库,而不是函数。
前端的模型不是真实模型
当然,您在客户端上持有的模型不是真实模型。您的实际模型和唯一的事实来源都存在于服务器上。我们使用API进行同步,但是如果两者之间存在冲突,那么数据库中的模型显然是最终的胜利者。
这为您提供了诸如折扣代码等之类的隐私权。您在前端找到的模型是真实模型的公共属性的同步版本,该模型是远程的。
业务逻辑可以存在于服务中。
假设您要编写一种方法来对模型执行某些操作,对其进行同步或进行验证(例如)。在其他框架中,您可能会想使用一种方法来扩展模型。在Angular中,您更有可能编写服务。
服务是单例对象。像其他任何JavaScript对象一样,您可以在其中放置函数或数据。Angular附带了一堆内置服务,例如$ http。您可以构建自己的应用程序,并使用依赖注入将它们自动提供给控制器。
服务可能包含与RESTful API进行通信或验证数据或可能需要执行的其他任何工作的方法。
服务不是模型
当然,您不应该将服务用作模型。将它们用作可以做事的对象。有时他们会对您的模型起作用。这是一种不同的思维方式,但可行的。
galleryService
可以存储画廊的阵列。