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的示例:
- 从数据库中获取的所有员工的hiredAt日期格式为:
YEAR-MONTH-DAY,例如2020-05-01 - 您需要以更友好的格式显示hiredAt日期:
年MONTH DAY,例如2020年5月1日 - 日期选择器使用以下格式:
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 建模