javascript 建模_使用JavaScript进行快速数据建模

javascript 建模

作为位于波兰克拉科夫的软件公司Railwaymen的后端开发人员 ,我的某些任务依赖于操作和定制从数据库检索的数据的模型。 当我想提高我在前端框架中的技能时,我选择了Vue ,并且我认为在存储中使用类似的方法来对数据进行建模是很好的。 我从一些通过NPM找到的库开始,但是它们提供了比我需要的更多的功能。

Evally-一个Web应用程序,可帮助企业跟踪员工的绩效评估和专业发展。 它提醒经理或人力资源代表有关员工即将进行的评估的信息,并收集以最公平的方式评估其绩效所需的所有数据。

型号及清单

您唯一需要做的就是在Lodash JavaScript库中创建一个类并使用defaultsDeep函数:

 _. defaultsDeep ( object , [ sources ] ) 

参数:

  • object (Object) :目标对象
  • [sources] (...Object) :源对象

返回值:

  • (Object) :返回对象

此帮助程序功能: Lodash文档

“将解析为未定义的所有目标属性的源对象递归拥有和继承的可枚举字符串键属性分配给目标对象。源对象从左到右应用。一旦设置了属性,该属性的其他值将被忽略。 ”

例如:


   
   
_. defaultsDeep ( { 'a' : { 'b' : 2 } } , { 'a' : { 'b' : 1 , 'c' : 3 } } )
  // => { 'a': { 'b': 2, 'c': 3 } }

就这样! 要进行尝试,请创建一个名为base.js的文件,并从Lodash包中导入defaultsDeep函数:


   
   
  // base.js
  import defaultsDeep from "lodash/defaultsDeep" ;

接下来,创建并导出Model类,其中构造函数将使用Lodash帮助器函数为所有传递的属性分配值,并使用默认值初始化未接收到的属性:


   
   
  // base.js
  // ...

  export class Model {
   constructor ( attributes = { } ) {
     defaultsDeep ( this , attributes , this . defaults ) ;
    }
  }

现在,使用firstName,lastName,position和hiredAt属性创建您的第一个实际模型Employee,其中“ position”将“ Programmer”定义为默认值:


   
   
  // employee.js
  import { Model } from "./base.js" ;

  export class Employee extends Model {
    get defaults ( ) {
      return {
       firstName : "" ,
       lastName : "" ,
       position : "Programmer" ,
       hiredAt : ""
      } ;
    }
  }

接下来,开始创建员工:


   
   
// app.js
  import { Employee } from "./employee.js" ;

  const programmer = new Employee ( {
   firstName : "Will" ,
   lastName : "Smith"
  } ) ;

  // => Employee {
  //   firstName: "Will",
  //   lastName: "Smith",
  //   position: "Programmer",
  //   hiredAt: "",
  //   constructor: Object
  // }

  const techLeader = new Employee ( {
   firstName : "Charles" ,
   lastName : "Bartowski" ,
   position : "Tech Leader"
  } ) ;

  // => Employee {
  //   firstName: "Charles",
  //   lastName: "Bartowski",
  //   position: "Tech Leader",
  //   hiredAt: "",
  //   constructor: Object
  // }

您有两个雇员,并且第一个雇员的职位是通过默认设置分配的。 定义多个员工的方法如下:


   
   
  // base.js

  // ...

  export class List {
   constructor ( items = [ ] ) {
      this . models = items. map ( item => new this . model ( item ) ) ;
    }
  }

   
   
  // employee.js
  import { Model , List } from "./base.js" ;

  // …

  export class EmployeesList extends List {
    get model ( ) {
      return Employee ;
    }
  }

List类构造函数将接收到的项目数组映射到所需模型的数组中。 唯一的要求是提供正确的模型类名称:


   
   
  // app.js
  import { Employee , EmployeesList } from "./employee.js" ;

  // …

  const employees = new EmployeesList ( [
    {
     firstName : "Will" ,
     lastName : "Smith"
    } ,
    {
     firstName : "Charles" ,
     lastName : "Bartowski" ,
     position : "Tech Leader"
    }
  ] ) ;

  // => EmployeesList {models: Array[2], constructor: Object}
  //  models: Array[2]
  //   0: Employee
  //     firstName: "Will"
  //     lastName: "Smith"
  //     position: "Programmer"
  //     hiredAt: ""
  //     <constructor>: "Employee"
  //   1: Employee
  //     firstName: "Charles"
  //     lastName: "Bartowski"
  //     position: "Tech Leader"
  //     hiredAt: ""
  //     <constructor>: "Employee"
  //   <constructor>: "EmployeesList"

使用这种方法的方法

这种简单的解决方案使您可以将数据结构放在一个位置,并避免代码重复。 DRY原理令人震惊 ! 您还可以根据需要自定义模型,例如以下示例。

定制吸气剂

您是否需要一个属性来依赖其他属性? 没问题; 您可以通过改善Employee模型来做到这一点:


   
   
// employee.js
  import { Model } from "./base.js" ;

  export class Employee extends Model {
    get defaults ( ) {
      return {
       firstName : "" ,
       lastName : "" ,
       position : "Programmer" ,
       hiredAt : ""
      } ;
    }

    get fullName ( ) {
      return [ this . firstName , this . lastName ] . join ( ' ' )
    }

  }

   
   
// app.js
  import { Employee , EmployeesList } from "./employee.js" ;

  // …

 console. log ( techLeader. fullName ) ;
  // => Charles Bartowski

现在,您不必重复执行代码即可像显示员工的全名一样简单。

日期格式

模型是为给定属性定义其他格式的好地方。 最好的例子是日期:


   
   
// employee.js
  import { Model } from "./base.js" ;
  import moment from 'moment' ;

  export class Employee extends Model {
    get defaults ( ) {
      return {
       firstName : "" ,
       lastName : "" ,
       position : "Programmer" ,
       hiredAt : ""
      } ;
    }

    get formattedHiredDate ( ) {
      if ( ! this . hiredAt ) return "---" ;

      return moment ( this . hiredAt ) . format ( 'MMMM DD, YYYY' ) ;
    }
  }

   
   
// app.js
  import { Employee , EmployeesList } from "./employee.js" ;

  // …

 techLeader. hiredAt = "2020-05-01" ;

 console. log ( techLeader. formattedHiredDate ) ;
  // => May 01, 2020

与日期(我发现开发Evally应用程序)有关的另一个案例是可以使用不同的日期格式进行操作。 这是使用datepicker的示例:

  1. 从数据库中获取的所有员工的hiredAt日期格式为:
    YEAR-MONTH-DAY,例如2020-05-01
  2. 您需要以更友好的格式显示hiredAt日期:
    年MONTH DAY,例如2020年5月1日
  3. 日期选择器使用以下格式:
    DAY-MONTHYEAR,例如01-05-2020

使用以下方法解决此问题:


   
   
// employee.js
  import { Model } from "./base.js" ;
  import moment from 'moment' ;

  export class Employee extends Model {

    // …

    get formattedHiredDate ( ) {
      if ( ! this . hiredAt ) return "---" ;

      return moment ( this . hiredAt ) . format ( 'MMMM DD, YYYY' ) ;
    }

    get hiredDate ( ) {
      return (
        this . hiredAt
          ? moment ( this . hiredAt ) . format ( 'DD-MM-YYYY' )
          : ''
      ) ;
    }

    set hiredDate ( date ) {
      const mDate = moment ( date , 'DD-MM-YYYY' ) ;
 
      this . hiredAt = (
       mDate. isValid ( )
          ? mDate. format ( 'YYYY-MM-DD' )
          : ''
      ) ;
    }
  }

这将添加getter和setter函数以处理datepicker的功能。


   
   
  // Get date from server
 techLeader. hiredAt = '2020-05-01' ;
 console. log ( techLeader. formattedHiredDate ) ;
  // => May 01, 2020

  // Datepicker gets date
 console. log ( techLeader. hiredDate ) ;
  // => 01-05-2020

  // Datepicker sets new date
 techLeader. hiredDate = '15-06-2020' ;

  // Display new date
 console. log ( techLeader. formattedHiredDate ) ;
  // => June 15, 2020

这使得管理多种日期格式变得非常简单。

模型类的另一个用途是存储与模型有关的常规信息,例如路由路径:


   
   
// employee.js
  import { Model } from "./base.js" ;
  import moment from 'moment' ;

  export class Employee extends Model {

    // …

    static get routes ( ) {
      return {
       employeesPath : '/api/v1/employees' ,
       employeePath : id => ` / api / v1 / employees / $ { id } `
      }
    }

  }

   
   
  // Path for POST requests
 console. log ( Employee. routes . employeesPath )

  // Path for GET request
 console. log ( Employee. routes . employeePath ( 1 ) )

自定义模型列表

不要忘记List类,您可以根据需要自定义它:


   
   
// employee.js
  import { Model , List } from "./base.js" ;

  // …

  export class EmployeesList extends List {
    get model ( ) {
      return Employee ;
    }

   findByFirstName ( val ) {
      return this . models . find ( item => item. firstName === val ) ;
    }

   filterByPosition ( val ) {
      return this . models . filter ( item => item. position === val ) ;
    }
  }

   
   
 console. log ( employees. findByFirstName ( 'Will' ) )
  // => Employee {
  //   firstName: "Will",
  //   lastName: "Smith",
  //   position: "Programmer",
  //   hiredAt: "",
  //   constructor: Object
  // }

 console. log ( employees. filterByPosition ( 'Tech Leader' ) )
  // => [Employee]
  //     0: Employee
  //       firstName: "Charles"
  //       lastName: "Bartowski"
  //       position: "Tech Leader"
  //       hiredAt: ""
  //       <constructor>: "Employee"

摘要

使用JavaScript进行数据建模的这种简单结构应为您节省一些开发时间。 您可以在需要时添加新功能,以使代码更整洁并易于维护。 我的CodeSandbox中提供了所有这些代码,请尝试一下,并在下面留下评论,让我知道它的运行方式。

翻译自: https://opensource.com/article/20/5/data-modeling-javascript

javascript 建模

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值