模型数据和行为的放置位置?

我正在与AngularJS合作进行我的最新项目。 在文档和教程中,所有模型数据都放入控制器范围。 我明白,必须在那里为控制器提供,并因此在相应的观点内。

但是我不认为模型应该在那里实际实施。 例如,它可能很复杂并且具有私有属性。 此外,人们可能希望在另一个上下文/应用程序中重用它。 把所有东西都放进控制器完全打破了MVC模式。

对于任何模型的行为也是如此。 如果我将使用DCI体系结构并从数据模型中分离行为,则必须引入其他对象来保持行为。 这将通过引入角色和上下文来完成。

当然,模型数据和行为可以用普通的javascript对象或任何“类”模式来实现。 但是AngularJS的做法是什么? 使用服务?

所以归结为这个问题:

遵循AngularJS最佳实践,您如何实现与控制器分离的模型?


如果您希望某些东西可用于多个控制器,则应该使用服务。 这是一个简单的人为的例子:

myApp.factory('ListService', function() {
  var ListService = {};
  var list = [];
  ListService.getItem = function(index) { return list[index]; }
  ListService.addItem = function(item) { list.push(item); }
  ListService.removeItem = function(item) { list.splice(list.indexOf(item), 1) }
  ListService.size = function() { return list.length; }

  return ListService;
});

function Ctrl1($scope, ListService) {
  //Can add/remove/get items from shared list
}

function Ctrl2($scope, ListService) {
  //Can add/remove/get items from shared list
}

我目前正在尝试这种模式,虽然不是DCI,但它提供了经典的服务/模型解耦(与Web服务交互的服务(又名模型CRUD)以及定义对象属性和方法的模型)。

请注意,只有当模型对象需要使用自己的属性的方法时,我才会使用这种模式,我可能会在任何地方使用(例如改进的getter / setter)。 我主张为系统地为每项服务做这件事。

编辑:我曾经认为这种模式会违背“角模型是普通的旧javascript对象”口头禅,但在我看来,这种模式是完全正常的。

编辑(2):为了更清楚,我使用一个模型类只是为了简单的getter / setters(例如:用于视图模板)。 对于大型商业逻辑,我建议使用“知道”模型的单独服务,但与其保持分离,并且只包含业务逻辑。 如果你愿意,可以称之为“业务专家”服务层

service / ElementServices.js (注意元素是如何在声明中注入的)

MyApp.service('ElementServices', function($http, $q, Element)
{
    this.getById = function(id)
    {
        return $http.get('/element/' + id).then(
            function(response)
            {
                //this is where the Element model is used
                return new Element(response.data);
            },
            function(response)
            {
                return $q.reject(response.data.error);
            }
        );
    };
    ... other CRUD methods
}

model / Element.js (使用angularjs Factory,用于创建对象)

MyApp.factory('Element', function()
{
    var Element = function(data) {
        //set defaults properties and functions
        angular.extend(this, {
            id:null,
            collection1:[],
            collection2:[],
            status:'NEW',
            //... other properties

            //dummy isNew function that would work on two properties to harden code
            isNew:function(){
                return (this.status=='NEW' || this.id == null);
            }
        });
        angular.extend(this, data);
    };
    return Element;
});

Angularjs文档明确指出:

与许多其他框架不同,Angular对模型没有限制或要求。 没有要继承的类或用于访问或更改模型的特殊访问器方法。 该模型可以是基元,对象哈希或完整对象类型。 简而言之,该模型是一个普通的JavaScript对象。

所以这意味着如何声明一个模型取决于你。 这是一个简单的Javascript对象。

我个人不会使用Angular Services,因为它们的行为与您可以使用的单例对象类似,例如,可以在整个应用程序中保持全局状态。

链接地址: http://www.djcxy.com/p/51867.html

上一篇: Where to put model data and behaviour?

下一篇: What stands behind asynchronicity in Javascript