npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

ts-mvc-model

v3.0.3

Published

**ts-mvc-model 使用说明**

Readme

ts-mvc-model 使用说明

1. 项目说明

说明

作用:提供一个实现 MVC模式,数据模型快速创建,运算 等功能

2. 安装与配置

npm i ts-mvc-model

yarn add ts-mvc-model
// tsconfig.json
// "experimentalDecorators": true,  开启 ts 的修饰器

{
    ...,
    "compilerOptions":{
        ...,
         "experimentalDecorators": true,
         ...,
    }
    ...
}

3. 功能说明

3.1 class声明

import { ModelBaseClass, ModelEnter } from "ts-mvc-model";

@ModelEnter()
class TestModel extends ModelBaseClass {

}

const testData = {};
const testItem = new TestModel(testData);
  • ModelBaseClass:是一个基础类型,定义的数据模型需要继承 ModelBaseClass
  • ModelEnter:数据模型入口修饰器。使用当前修饰器注册数据模型

3.2 属性修饰器

  • 参考案例:
import { 
    ModelBaseClass, 
    ModelEnter, 
    ModelCol, 
    ModelAutoUUID, 
    ModelPath 
} from "ts-mvc-model";

@ModelEnter()// 使用 ModelEnter 注册一个 数据模型
export class TestSubModel extends ModelBaseClass {
  @ModelPath({type: 'id'})// 标记这是树状结构中,当前层的唯一标识
  @ModelAutoUUID()
  id = "";

  @ModelCol({})
  test = "";
}

@ModelEnter()// 使用 ModelEnter 注册一个 数据模型
export class TestModel extends ModelBaseClass {
  @ModelPath({type: 'id'})// 标记这是树状结构中,当前层的唯一标识
  @ModelAutoUUID()// 自动生成一个全局唯一的 id
  id = "";

  // 普通属性,直接通过数据源赋值
  @ModelCol({})
  test2 = "";
  
  // test3 为 TestSubModel 类型的对象
  @ModelCol({
      type: 'object',
      objectItem: TestSubModel
  })
  test3: TestSubModel|undefined;

  
  @ModelPath({type: 'source'})// 标记 test4 是树状展开的 数据源
  @ModelCol({
      type: 'array',
      arrayItem: TestSubModel
  })// test4 为 TestSubModel 类型的数组 
  test4: Array<TestSubModel> = [];
}
  • ModelAutoUUID:一个自动生成全局唯一标识的修饰器
  • ModelCol:属性修饰器,用于声明数据模型中的属性(数据模型中只有被ModelCol 修饰器标识的属性,才会在初始化的时候自动初始化数据)
  • ModelPath:路径修饰器,用于标记树状类型的路径与生成tableV2 树状数据渲染需要的path参数

3.3 生命周期

  • _init_
import { ModelBaseClass, ModelEnter, ModelCol, ModelAutoUUID } from "ts-mvc-model";

@ModelEnter()
export class TestModel extends ModelBaseClass {
  @ModelAutoUUID()
  id = "";

  @ModelCol({})
  test = "";
  
  _init_(...p: any): void {
      // p: new 初始化的参数集合
      // 可以使用 this,对当前数据模型中的 数据再次处理
      
      console.log(this.test);
      this.test = 'xxxxxx'
  }

}
  • 类型:回调函数(非必选)
  • 调用时机:当前数据模型 New 初始化完成之后(在类的constructor方法完成之后)
  • 作用:可以使用this获取数据模型中的任何属性,对当前数据模型进行初始化后的再次处理
  • _initUUID_
import { ModelBaseClass, ModelEnter, ModelCol, ModelAutoUUID } from "ts-mvc-model";

@ModelEnter()
export class TestModel extends ModelBaseClass {
  @ModelAutoUUID()
  id = "";

  @ModelCol({})
  test = "";
  
  _initUUID_(oldUuid: string): string {
      return '自定义的uuid'
  }

}
  • 类型:回调函数(非必选)
  • 调用时机:ModelAutoUUID 修饰器生成唯一标识的时候
  • 作用:自定义生成的uuid

3.4 内置方法

  • 基础案例数据:
import { 
    ModelBaseClass, 
    ModelEnter, 
    ModelCol, 
    ModelAutoUUID, 
    ModelPath 
} from "ts-mvc-model";

@ModelEnter()
export class TestSubModel extends ModelBaseClass {
  @ModelPath({type: id})// 标记这是树状结构中,当前层的唯一标识
  @ModelAutoUUID()
  id = "";

  @ModelCol({})
  subTest = "";
}

@ModelEnter()
export class TestModel extends ModelBaseClass {
  @ModelPath({type: id})// 标记这是树状结构中,当前层的唯一标识
  @ModelAutoUUID()// 自动生成一个全局唯一的 id
  id = "";

  // 普通属性,直接通过数据源赋值
  @ModelCol({})
  test2 = "";
  
  // test3 为 TestSubModel 类型的对象
  @ModelCol({
      type: 'object',
      objectItem: TestSubModel
  })
  test3: TestSubModel;

  
  @ModelPath({type: 'source'})// 标记 test4 是树状展开的 数据源
  @ModelCol({
      type: 'array',
      arrayItem: TestSubModel
  })// test4 为 TestSubModel 类型的数组 
  test4: Array<TestSubModel>;
}
  • _OTD_
  1. 实例方法:数据模型生成数据对象的内置方法。
_OTD_(): any {
    //...
}
const subData = { subTest: 'subTest' };
const data = {test2: 'test2', test3: subData, test4: [subData] }
const testModel: TestModel = new TestModel(data);

const obj = testModel._OTD_();

console.log(obj);

/*
{
    test2: 'test2', 
    test3:  { 
        subTest: 'subTest' 
    },
    test4: [
        {subTest: 'subTest'},
        {subTest: 'subTest'}
    ]
}
*/
  • _init_path_
_init_path_(basePath: Array<string | number> = [], pathName?: string): Array<string | number>{
    //...
}
  1. 实例方法:动态递归初始化树状数据中的path,在数据模型中会生成一个 _path_:Array<string> 参数。
  1. 未指定特殊的pathName,数据模型在初始化时默认会自动调用当前方法
  1. 参数:
  1. basePath: Array<string | number> = []; 为生成的路径 添加前置基础路径,默认为空
  1. pathName?: string; 生成指定路径时使用,生成路径时,会根据pathName匹配 ModelPath 修饰器中的pathName,使用匹配到的ModelPath({type: 'id'}) 生成路径
// 默认生成 path

const subData = { subTest: 'subTest' };
const data = {test2: 'test2', test3: subData, test4: [subData] }
const testModel: TestModel = new TestModel(data);

// log testModel

/*
{
    id: '1',
    test2: 'test2',
    test3: [
        {
            id: '2',
            subTest: 'subTest',
            _path_: ['1', '2']
        },
        {
            id: '3',
            subTest: 'subTest',
            _path_: ['1', '3']
        },
    ],
    _path_: ['1']
}

*/
  • _tree_to_list_
  1. 实例方法:树状结构数据模型展开成 列表 类型数据结构
_init_path_(basePath: Array<string | number> = [], pathName?: string): Array<string | number>{
    //...
}
const subData = { subTest: 'subTest' };
const data = {test2: 'test2', test3: subData, test4: [subData] }
const dataList = [data, data];

const tree: Array<TestModel> = dataList.map((item) => new TestModel(item));

const list: Array<TestModel> = [];
tree.forEach((item) => item._init_path_(list))

// log list
/*
[
   {
       id: '1',
       test2: 'test2',
       test3: [
        ...
       ],
       _path_: ['1']
   },
   {
        id: '2',
        subTest: 'subTest',
        _path_: ['1', '2']
    },
    {
        id: '3',
        subTest: 'subTest',
        _path_: ['1', '3']
    },
   {
       id: '4',
       test2: 'test2',
       test3: [
        ...
       ],
       _path_: ['4']
   },
   {
        id: '5',
        subTest: 'subTest',
        _path_: ['4', '5']
    },
    {
        id: '6',
        subTest: 'subTest',
        _path_: ['4', '6']
    },
]
*/
  • _copy_
_copy_(deep?: boolean) {
    return any;
}
  1. 实例方法:用于复制当前数据模型,生成一个新的数据模型
  1. 参数:
  1. deep:非必填。默认为非深拷贝,只会copy数据模型第一层。当deep为true时,会递归复制 type为'array'和'objecg'的属性
  • InitWithList
  1. 静态类方法:快速初始化列表数据源的
static InitWithList<T>(items: Array<any>): Array<T> {
    //...
}
const subData = { subTest: 'subTest' };
const data = {test2: 'test2', test3: subData, test4: [subData] }
const dataList = [data, data];

// 使用 map 创建
// const tree: Array<TestModel> = dataList.map((item) => new TestModel(item));

const tree: Array<TestModel> = TestModel.InitWithList<TestModel>(dataList);
  • TreeToList
  1. 静态类方法:快速把数据模型从 tree 拉平成 list
  1. 参数说明:
  1. array: 需要拉平的tree数据模型
  1. pathName:指定tree数据展开路径的自定义名称。如果设置,会根据pathName匹配 ModelPath 修饰器中的pathName,使用匹配到的ModelPath({type: 'source'}) 生成路径
static TreeToList<T extends ModelBaseClass>(array: Array<T>, pathName?: string): Array<T> {
    // ...
}
const subData = { subTest: 'subTest' };
const data = {test2: 'test2', test3: subData, test4: [subData] }
const dataList = [data, data];

const tree: Array<TestModel> = TestModel.InitWithList<TestModel>(dataList);
const list: Array<TestModel> = TestModel.TreeToList(tree);

// log list
/*
[
   {
       id: '1',
       test2: 'test2',
       test3: [
        ...
       ],
       _path_: ['1']
   },
   {
        id: '2',
        subTest: 'subTest',
        _path_: ['1', '2']
    },
    {
        id: '3',
        subTest: 'subTest',
        _path_: ['1', '3']
    },
   {
       id: '4',
       test2: 'test2',
       test3: [
        ...
       ],
       _path_: ['4']
   },
   {
        id: '5',
        subTest: 'subTest',
        _path_: ['4', '5']
    },
    {
        id: '6',
        subTest: 'subTest',
        _path_: ['4', '6']
    },
]
*/

4. 一些使用场景

  1. 数据没有唯一标识,前端快速生成一个唯一标识
import { 
    ModelBaseClass, 
    ModelEnter, 
    ModelCol, 
    ModelAutoUUID, 
} from "ts-mvc-model";

@ModelEnter()
export class TestModel extends ModelBaseClass {
  @ModelAutoUUID()
  id = "";

  @ModelCol({})
  test = "";
}
  1. 服务端数据源字段命名发生变化,前端通过数据模型实现数据映射
import { 
    ModelBaseClass, 
    ModelEnter, 
    ModelCol
} from "ts-mvc-model";

@ModelEnter()
export class TestModel extends ModelBaseClass {
  @ModelCol({
      key: 'testt'
  })// 服务端返回的数据 字段名:testt,数据模型数据名:test
  test = "";
}
  1. 服务端数据源字段类型发生变化,前端通过数据模型实现数据映射
import { 
    ModelBaseClass, 
    ModelEnter, 
    ModelCol
} from "ts-mvc-model";

@ModelEnter()
export class TestModel extends ModelBaseClass {
  @ModelCol({
      key: 'test'
  })
  test: Array<string> = [];
  
  //  前端希望展示 通过 ‘|’ 拼接的 test数组中的数据
  @ModelCol({
      key: 'test',
      formatValue:(value: Array<string>)=>{
          return value.join('|')
      }
  })
  testStr = '';
}

const data = {test: ['a', 'b']};
const testModel = new TestModel(data);

// log testModel
/*
{
    test:  ['a', 'b'],
    testStr: 'a|b'
}
*/
  1. 前端组件入参数据格式与最终提交数据格式不一致,前端进行数据转换
import { 
    ModelBaseClass, 
    ModelEnter, 
    ModelCol
} from "ts-mvc-model";

@ModelEnter()
export class TestModel extends ModelBaseClass {

    // 前端复选组件 生成的数据是 字符串列表,服务端需要接收 使用逗号分隔的  字符串
  @ModelCol({
      key: 'test',
      formatData: (value: Array<string>)=> {
          return value.join(',')
      }
  })
  test: Array<string> = [];
}

const data = {test: []};
const testModel = new TestModel(data);

// 模拟组件赋值
/*
<select v-model="testModel.test">
    <option>...</option>
</select>
*/
testModel.test = ['a', 'b'];
const submitData = testModel._OTD_();

// log submitData
/*
{
    test: 'a,b',
}
*/