• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com专业计算机教程网站
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • html/xhtml
  • html5
  • CSS
  • XML/XSLT
  • Dreamweaver教程
  • Frontpage教程
  • 心得技巧
  • bootstrap
  • vue
  • AngularJS
  • HBuilder教程
  • css3
  • 浏览器兼容
  • div/css
  • 网页编辑器
  • axure
您的位置:首页 > 网页设计 >AngularJS > 在AngularJS框架中处理数据建模的方式解析

在AngularJS框架中处理数据建模的方式解析

作者:Naor Yehudaey 字体:[增加 减小] 来源:互联网 时间:2017-05-30

本文主要包含在AngularJS框架中处理数据建模的方式解析等相关知识,Naor Yehudaey 希望在学习及工作中可以帮助到您

我们知道,AngularJS并没有自带立等可用的数据建模方案。而是以相当抽象的方式,让我们在controller中使用JSON数据作为模型。但是随着时间的推移和项目的成长,我意识到这种建模的方式不再能满足我们项目的需求。在这篇文章中我会介绍在我的AngularJS应用中处理数据建模的方式。

为Controller定义模型

让我们从一个简单的例子开始。我想要显示一个书本(book)的页面。下面是控制器(Controller):

BookController

app.controller('BookController', ['$scope', function($scope) {
  $scope.book = {
    id: 1,
    name: 'Harry Potter',
    author: 'J. K. Rowling',
    stores: [
      { id: 1, name: 'Barnes & Noble', quantity: 3},
      { id: 2, name: 'Waterstones', quantity: 2},
      { id: 3, name: 'Book Depository', quantity: 5}
    ]
  };
}]);
</div>

这个控制器创建了一个书本的模型,我们可以在后面的模板中(templage)中使用它。

template for displaying a book

<div ng-controller="BookController">
  Id: <span ng-bind="book.id"></span>
   
  Name:<input type="text" ng-model="book.name" />
   
  Author: <input type="text" ng-model="book.author" />
</div>
</div>

假如我们需要从后台的api获取书本的数据,我们需要使用$http:
BookController with $http

app.controller('BookController', ['$scope', '$http', function($scope, $http) {
  var bookId = 1;
 
  $http.get('ourserver/books/' + bookId).success(function(bookData) {
    $scope.book = bookData;
  });
}]);
</div>

注意到这里的bookData仍然是一个JSON对象。接下来我们想要使用这些数据做一些事情。比如,更新书本信息,删除书本,甚至其他的一些不涉及到后台的操作,比如根据请求的图片大小生成一个书本图片的url,或者判断书本是否有效。这些方法都可以被定义在控制器中。

BookController with several book actions

app.controller('BookController', ['$scope', '$http', function($scope, $http) {
  var bookId = 1;
 
  $http.get('ourserver/books/' + bookId).success(function(bookData) {
    $scope.book = bookData;
  });
 
  $scope.deleteBook = function() {
    $http.delete('ourserver/books/' + bookId);
  };
 
  $scope.updateBook = function() {
    $http.put('ourserver/books/' + bookId, $scope.book);
  };
 
  $scope.getBookImageUrl = function(width, height) {
    return 'our/image/service/' + bookId + '/width/height';
  };
 
  $scope.isAvailable = function() {
    if (!$scope.book.stores || $scope.book.stores.length === 0) {
      return false;
    }
    return $scope.book.stores.some(function(store) {
      return store.quantity > 0;
    });
  };
}]);
</div>

然后在我们的模板中:

template for displaying a complete book

<div ng-controller="BookController">
  <div ng-style="{ backgroundImage: 'url(' + getBookImageUrl(100, 100) + ')' }"></div>
  Id: <span ng-bind="book.id"></span>
   
  Name:<input type="text" ng-model="book.name" />
   
  Author: <input type="text" ng-model="book.author" />
   
  Is Available: <span ng-bind="isAvailable() ? 'Yes' : 'No' "></span>
   
  <button ng-click="deleteBook()">Delete</button>
   
  <button ng-click="updateBook()">Update</button>
</div>
</div>

在controllers之间共享Model
如果书本的结构和方法只和一个控制器有关,那我们现在的工作已经可以应付。但是随着应用的增长,会有其他的控制器也需要和书本打交道。那些控制器很多时候也需要获取书本,更新它,删除它,或者获得它的图片url以及看它是否有效。因此,我们需要在控制器之间共享这些书本的行为。我们需要使用一个返回书本行为的factory来实现这个目的。在动手写一个factory之前,我想在这里先提一下,我们创建一个factory来返回带有这些book辅助方法的对象,但我更倾向于使用prototype来构造一个Book类,我觉得这是更正确的选择:

Book model service

app.factory('Book', ['$http', function($http) {
  function Book(bookData) {
    if (bookData) {
      this.setData(bookData):
    }
    
// Some other initializations related to book
  };
  Book.prototype = {
    setData: function(bookData) {
      angular.extend(this, bookData);
    },
    load: function(id) {
      var scope = this;
      $http.get('ourserver/books/' + bookId).success(function(bookData) {
        scope.setData(bookData);
      });
    },
    delete: function() {
      $http.delete('ourserver/books/' + bookId);
    },
    update: function() {
      $http.put('ourserver/books/' + bookId, this);
    },
    getImageUrl: function(width, height) {
      return 'our/image/service/' + this.book.id + '/width/height';
    },
    isAvailable: function() {
      if (!this.book.stores || this.book.stores.length === 0) {
        return false;
      }
      return this.book.stores.some(function(store) {
        return store.quantity > 0;
      });
    }
  };
  return Book;
}]);
</div>

这种方式下,书本相关的所有行为都被封装在Book服务内。现在,我们在BookController中来使用这个亮眼的Book服务。

BookController that uses Book model

app.controller('BookController', ['$scope', 'Book', function($scope, Book) {
  $scope.book = new Book();
  $scope.book.load(1);
}]);
</div>

正如你看到的,控制器变得非常简单。它创建一个Book实例,指派给scope,并从后台加载。当书本被加载成功时,它的属性会被改变,模板也随着被更新。记住其他的控制器想要使用书本功能,只要简单地注入Book服务即可。此外,我们还要改变template使用book的方法。

template that uses book instance

<div ng-controller="BookController">
  <div ng-style="{ backgroundImage: 'url(' + book.getImageUrl(100, 100) + ')' }"></div>
  Id: <span ng-bind="book.id"></span>
   
  Name:<input type="text" ng-model="book.name" />
   
  Author: <input type="text" ng-model="book.author" />
   
  Is Available: <span ng-bind="book.isAvailable() ? 'Yes' : 'No' "></span>
   
  <button ng-click="book.delete()">Delete</button>
   
  <button ng-click="book.update()">Update</button>
</div>
</div>

到这里,我们知道了如何建模一个数据,把他的方法封装到一个类中,并且在多个控制器中共享它,而不需要写重复代码。
在多个控制器中使用相同的书本模型

我们定义了一个书本模型,并且在多个控制器中使用了它。在使用了这种建模架构之后你会注意到有一个严重的问题。到目前为止,我们假设多个控制器对书本进行操作,但如果有两个控制器同时处理同一本书会是什么情况呢?

假设我们页面的一块区域我们所有书本的名称,另一块区域可以更新某一本书。对应这两块区域,我们有两个不同的控制器。第一个加载书本列表,第二个加载特定的一本书。我们的用户在第二块区域中修改了书本的名称并且点击“更新”按钮。更新操作成功后,书本的名称会被改变。但是在书本列表中,这个用户始终看到的是修改之前的名称!真实的情况是我们对同一本书创建了两个不同的书本实例——一个在书本列表中使用,而另一个在修改书本时使用。当用户修改书本名称的时候,它实际上只修改了后一个实例中的属性。然而书本列表中的书本实例并未得到改变。

解决这个问题的办法是在所有的控制器中使用相同的书本实例。在这种方式下,书本列表和书本修改的页面和控制器都持有相同的书本实例,一旦这个实例发生变化,就会被立刻反映到所有的视图中。那么按这种方式行动起来,我们需要创建一个booksManager服务(我们没有大写开头的b字母,是因为这是一个对象而不是一个类)来管理所有的书本实例池,并且富足返回这些书本实例。如果被请求的书本实例不在实例池中,这个服务会创建它。如果已经在池中,那么就直接返回它。请牢记,所有的加载书本的方法最终都会被定义在booksManager服务中,因为它是唯一的提供书本实例的组件。

booksMa

您可能想查找下面的文章:

相关文章

  • 2017-05-30Angularjs 自定义服务的三种方式(推荐)
  • 2017-05-30使用Chrome浏览器调试AngularJS应用的方法
  • 2017-05-30如何使用AngularJs打造权限管理系统【简易型】
  • 2017-05-30详解Angular-Cli中引用第三方库
  • 2017-05-30angularJS深拷贝详解
  • 2017-05-30AngularJS在IE8的不支持的解决方法
  • 2017-05-30AngularJS出现$http异步后台无法获取请求参数问题的解决方法
  • 2017-05-30Angular开发者指南之入门介绍
  • 2017-05-30Angularjs中使用layDate日期控件示例
  • 2017-05-30Angularjs中如何使用filterFilter函数过滤

文章分类

  • html/xhtml
  • html5
  • CSS
  • XML/XSLT
  • Dreamweaver教程
  • Frontpage教程
  • 心得技巧
  • bootstrap
  • vue
  • AngularJS
  • HBuilder教程
  • css3
  • 浏览器兼容
  • div/css
  • 网页编辑器
  • axure

最近更新的内容

    • AngularJS Module方法详解
    • 详解Angular2 关于*ngFor 嵌套循环
    • 使用JavaScript的AngularJS库编写hello world的方法
    • Angular.js中$apply()和$digest()的深入理解
    • AngularJS系列(九)——模块
    • angularjs实现首页轮播图效果
    • AngularJS实现Model缓存的方式
    • AngularJs 弹出模态框(model)
    • AngularJS数据源的多种获取方式汇总
    • AngularJS $injector 依赖注入详解

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有