> For the complete documentation index, see [llms.txt](https://narro.gitbook.io/tinyts-handbook-cn/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://narro.gitbook.io/tinyts-handbook-cn/introduction/viewmodels.md).

# 视图模型

让我们先来看一个简单的视图模型类。

```typescript
import {BaseViewModel} from 'tinyts/core/Core';

export class PromiseModel extends BaseViewModel {
    RegisterEvents() {

    }
}
```

这是一个空的ViewModel类，我们可以注意到，该类继承了一个来自于tinyts核心库的类`BaseViewModel`。让我们先查看一下BaseViewModel的[源码](https://github.com/narrowizard/tinyts/blob/master/core/Core.ts)。\
可以看到，BaseViewModel是一个抽象类，这个类实现了一个构造方法，并包含一个抽象方法`RegisterEvents`。该类在构造方法中实现了控件属性以及子视图属性的注入（将在后续的章节中介绍注入流程）。\
我们在这里了解一下BaseViewModel中的几个方法是干什么的。

* RegisterEvents —— 该方法用于注册ViewModel中控件的事件，如按钮的点击事件等。
* OnValidateError —— 该方法用于处理控件验证的错误。（控件验证将会在后续章节中介绍）
* OnLoad —— 该方法在ViewModel加载完成后被调用。

  接下来，让我们为这个ViewModel添加一些功能。首先看一下我们的html页面：

  ```markup
  <div>
  请输入你的名字：<input type="text" id="txtName" />
  <button type="button" id="btnSubmt" >确定</button>
  </div>
  ```

  受篇幅影响，我们在这里省略了html的大部分结构，只展示了与内容相关的部分。我们在页面上放置了一个输入框#txtName和一个按钮#btnSubmit。当点击确定按钮的时候，我们想对你发出一声问候。接下来看我们如何在ViewModel中实现这些功能。首先使用view decorator来声明两个控件属性。

  ```typescript
  @view(TextBox)
  txtName:TextBox;

  @view(Button)
  btnSubmit:Button;
  ```

  在使用之前，必须要从tinyts中引入这些类和方法。

  ```typescript
  import {view} from 'tinyts/core/Core';
  import {TextBox} from 'tinyts/controls/TextBox';
  import {Button} from 'tinyts/controls/Button';
  ```

  接下来在RegisterEvents方法中为确定按钮注册事件：

  ```typescript
  RegisterEvents() {
     var me = this;
     this.btnSubmit.OnClick(() => {
         alert(`${me.txtName.Value()}，你好！`);
     });
  }
  ```

  到此为止，我们已经基本完成了这个简单的功能。完整的代码请查看[这里](https://github.com/narrowizard/tinyts-demo/blob/dev/viewmodels/handbook/vm.ts)。值得注意的是，我们并没有在ViewModel的任何地方初始化txtName和btnSubmit这两个属性，也没有将其绑定到html上的元素，而是直接就拿来使用了。这就是上一节讲到的依赖注入，BaseViewModel已经帮我们完成了这些工作。这里简要介绍一下注入的过程：\
  BaseViewModel初始化的时候，会查找自己的属性中是否包含了被@view以及@partialView装饰的属性，如果存在，就认为该属性作为一个控件属性或者子视图属性需要被注入并绑定到html元素。BaseViewModel会检查@view的参数，如果该参数继承自View，则初始化该类并将该对象绑定到html元素（以该对象在ViewModel中的属性名为id进行绑定），否则绑定出错。子视图的注入过程与控件类似。
