Javascript Angular.js中模型状态应存储在何处

Javascript Angular.js中模型状态应存储在何处,javascript,model,angularjs,state,Javascript,Model,Angularjs,State,我发现Angular对模型的使用令人困惑。Angular似乎采取了一种方法,即模型可以是您喜欢的任何东西,即Angular不包含显式模型类,您可以使用普通JavaScript对象作为模型 在我所看到的几乎每一个示例中,模型实际上都是一个对象,或者是手工创建的,或者是通过资源从API调用返回的。因为我看到的几乎每个角度示例都很简单,通常存储在控制器中$scope上的模型数据以及与模型相关的任何状态(例如选择)也存储在控制器中的$scope上。这适用于简单的应用程序/示例,但当应用程序变得更复杂时,

我发现Angular对模型的使用令人困惑。Angular似乎采取了一种方法,即模型可以是您喜欢的任何东西,即Angular不包含显式模型类,您可以使用普通JavaScript对象作为模型

在我所看到的几乎每一个示例中,模型实际上都是一个对象,或者是手工创建的,或者是通过资源从API调用返回的。因为我看到的几乎每个角度示例都很简单,通常存储在控制器中$scope上的模型数据以及与模型相关的任何状态(例如选择)也存储在控制器中的$scope上。这适用于简单的应用程序/示例,但当应用程序变得更复杂时,这似乎过于简单了。例如,存储在控制器中的模型状态有变为上下文并在上下文发生变化时丢失的风险;存储
selectedGallery
selectedPhoto
的控制器只能存储全局
selectedImage
,而不能存储每个库的
selectedPhoto
。在这种情况下,在每个库中使用控制器可能会消除此问题,但从UI的角度来看,这似乎是浪费,可能是不合适和不必要的

角的模型定义似乎更接近于我所认为的Vo/DTO,它是一个在服务器和客户端之间传递的哑对象。我的本能是把这样一个对象包装在我将要考虑的模型中——一个保持与DTO /VO(如选择)相关的状态的类,根据需要提供调制器来操纵DTO /VO,并通知其他应用程序对基础数据的更改。显然,Angular的绑定很好地处理了最后一部分,但我仍然看到了前两个职责的强大用例

<>但是我还没有看到我所看到的例子中所用的模式,但是我也没有看到我认为是一个可扩展的替代品。Angular似乎通过强制使用单例(我知道有一些方法可以绕过这一点,但它们似乎没有得到广泛的使用或认可),从而暗中不鼓励使用服务作为模型

那么,我应该如何保持模型数据的状态呢


[编辑]中的第二个答案很有趣,与我当前使用的答案很接近。

Angular对如何存储您所谓的“模型对象”没有意见。角度控制器
$scope
仅作为“视图模型”存在,用于管理用户界面。我建议在代码中分离这两个概念

如果您想要角度范围更改通知的精确性(
$watch
),您可以使用范围对象来存储模型数据,如果您愿意(
var myScope=$rootScope.$new()
)。只是不要使用与UI绑定到的同一个范围对象

我建议为此编写定制服务。因此,数据流如下所示:

AJAX-->自定义服务-->模型范围对象-->控制器-->UI范围对象-->DOM

或者这个:


AJAX-->自定义服务-->普通旧JavaScript对象-->控制器-->UI范围对象-->DOM

首先,不要忘记Angular是一个基于web的框架,如果仅在对象中“保持状态”,它将无法在用户在其浏览器上点击刷新后继续存在。因此,弄清楚如何在基于web的应用程序中保持模型数据的状态意味着弄清楚如何将其持久化,以便代码在浏览器环境中运行

Angular可让您通过以下方式轻松保持状态:

  • 对RESTful$资源的调用
  • 表示模型实例的URL
  • 在您的简单示例中,用户操作的存储,如
    selectedGallery
    selectedPhoto
    可以使用URL表示,如下所示:

    // List of galleries
    .../gallery
    
    // List of photos in a gallery
    .../gallery/23
    
    // A specific photo
    .../gallery/23/photo/2
    
    URL非常重要,因为它允许用户使用
    后退
    前进
    按钮浏览浏览器历史记录。如果您希望与应用程序的其他部分共享此状态,web应用程序提供了丰富的方法,您可以使用cookie/localStorage、隐藏帧/字段甚至将其存储在服务器中来完成此操作

    一旦定义了如何持久化应用程序不同状态的策略,就应该更容易决定是否要使用
    提供的单例对象访问这些持久化信息。服务
    或通过
    的实例。工厂

    状态(和模型)存储在$scope中 $scope是Angular的数据存储对象。它类似于一个数据库$范围本身不是模型,但可以将模型存储在$scope中

    每个$scope都有一个父$scope,一直到$rootScope,形成一个松散镜像DOM的树结构。当您调用需要新$scope的指令(例如ng controller)时,将创建一个新的$scope对象并将其添加到树中

    $scope对象使用原型继承进行连接。这意味着,如果在树中较高级别添加模型,则该模型将可用于所有较低级别。这是一个非常强大的特性,它使$scope层次结构对模板作者几乎是透明的

    控制器初始化$scope 控制器的目的是初始化$scope。同一控制器可以初始化页面不同部分中的许多$scope对象。控制器被实例化,设置$scope对象,然后退出。您可以使用同一控制器初始化页面不同部分中的多个$scope

    对于图像库,您将拥有一个imageGallery控制器,然后使用ng控制器指令将该控制器应用于希望成为库的DOM的每个部分。页面的这一部分将获得它自己的$scope,您将使用它来存储selectedPhoto属性

    原型范围 $scope始终使用普通的旧原型继承从其父级继承