惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

S
Schneier on Security
A
Arctic Wolf
S
Security Affairs
O
OpenAI News
SecWiki News
SecWiki News
TaoSecurity Blog
TaoSecurity Blog
H
Heimdal Security Blog
T
Threat Research - Cisco Blogs
Hacker News: Ask HN
Hacker News: Ask HN
N
News | PayPal Newsroom
Google Online Security Blog
Google Online Security Blog
C
Cisco Blogs
The Hacker News
The Hacker News
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
C
CXSECURITY Database RSS Feed - CXSecurity.com
P
Privacy International News Feed
V
Vulnerabilities – Threatpost
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
酷 壳 – CoolShell
酷 壳 – CoolShell
H
Hacker News: Front Page
T
Tenable Blog
T
The Exploit Database - CXSecurity.com
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Spread Privacy
Spread Privacy
人人都是产品经理
人人都是产品经理
www.infosecurity-magazine.com
www.infosecurity-magazine.com
V2EX - 技术
V2EX - 技术
L
LINUX DO - 最新话题
The GitHub Blog
The GitHub Blog
博客园 - 三生石上(FineUI控件)
T
The Blog of Author Tim Ferriss
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
V
Visual Studio Blog
The Cloudflare Blog
N
News and Events Feed by Topic
量子位
Google DeepMind News
Google DeepMind News
Application and Cybersecurity Blog
Application and Cybersecurity Blog
L
LINUX DO - 热门话题
P
Palo Alto Networks Blog
Stack Overflow Blog
Stack Overflow Blog
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Attack and Defense Labs
Attack and Defense Labs
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Hacker News - Newest:
Hacker News - Newest: "LLM"
Apple Machine Learning Research
Apple Machine Learning Research
The Register - Security
The Register - Security
Microsoft Security Blog
Microsoft Security Blog
Know Your Adversary
Know Your Adversary
Webroot Blog
Webroot Blog

博客园 - lswweb

Drone概念与答疑 Drone基于K8S的Secrets管理 Centos8通过X11使用GUI应用 Linux自己常用命令记录(待续) K8S Master节点灾备与恢复 - ETCD K8S Master节点灾备与恢复 - Host文件Copy Rook Ceph出现daemons have recently crashed异常 Ceph rbd删除image遭遇watchers异常处理 Ceph OSD更换硬盘后遭遇PG Inconsistent异常与处理 Rook Ceph OSD异常,格式化osd硬盘重新挂载 进入K8S Pod执行操作,遭遇Operation not permitted错误 K8S Pod挂载rook ceph pv报not found in the list of registered CSI drivers异常处理 Vs中调试MVC源代码步骤 手动创建vsct文件 快速查找找VS菜单信息(Guid、GuidId、CmdId等) 在多排序条件下SQL获文章上一条、下一条记录 Asp.Net MVC 表单验证 AjaxOptions.OnSuccess回调方法返回的参数信息 一次自定义Configuration的悲惨经历。
Knockout中ViewModel与Model的互转
lswweb · 2014-04-18 · via 博客园 - lswweb

    在我们平常的开发当中使用频率最多的就是CRUD(添加、更新、删除、查询)。 而“添加”和“编辑”操作又是整个数据源的入口,在整个CRUD中占有非常重要的地位。常规情况下我们做一个编辑操作时,首先需要将实体对象从数据库中提取出来并将其值展示在页面上供用户进行编辑。用户编辑完成之后点击提交按钮时我们需要再将实体对象的值从页面中提取出来,并组成一个完整的实体对象提后交到后台进行处理。

    那么这种业务场景我们如何来使用knockout来完成呢?ko是一种MVVM(Model-View-ViewModel)模式的应用,本质上我们的实体对象是一个数据模型也就是model,如果我们想要它展示在View上边那么就需要将它转化为ViewModel。同理,如果我们想要取得页面的数据信息,那么也就需要再将ViewModel转换为model。这样我们需要解决的两个是:

    1、展示数据时我们需要将model转换为ViewModel 。

    2、提交数据之前,我们需要将ViewModel转换为model对象

Model转换为ViewModel

    ko的监控机制是一个典型的“观查者”模式的实现。ko.observable()方法将对象转换为一个监控对象,即:“被观察者”,通过使用“被观察者”的subscribe方法来注册“观查者”。首先,我们定义一个实体对象(entity)并将它监控起来,然后我们订阅一个专门的用来将Model转换为ViewModel的Listener。当这个Listener接收到entity发生变化的通知时,将对entity的属性进行检测,如果它没有被监控,则将它转换为一个监控对象。ko.isObservable是ko官方提供的一个辅助API,它返回一个Boolean值,用来判断对象是否已经被ko监控。

//案例视图模型
function viewModel() {
    var model = this;

    //使用ko.observable将实体对象监控起来
    this.entity = ko.observable()

    //注册一个用来将entity转换为viewModel的listener
    this.entity.subscribe(function (newValue) {
                    
        //判断属性children是否已经被监控
        if (newValue && !ko.isObservable(newValue.children)) {
            //将children属性转为监控对象
            newValue.children = ko.observableArray(newValue.children || []);
            //将name属性转换为监控对象
            newValue.name = ko.observable(newValue.name);
        }
    });
}

ViewModel转换为Model

    将ViewModel转换为Model是一个让很多新手很痛苦的地方。常规情况下因为entity的属性因在转换为ViewModel时被转换为“被观察者”也就是由属性变成了一个函数,我们需要它再次将它转回为属性。并且因为ViewModel和页面显示是直接相关联的,我们这时候还不能直接修改entity对象,因为一旦发生修改,那么页面也跟随着发生变化。所以实际上我们需要clone一个entity对象,并将监控对象转换为属性。这个过程相对来讲比较麻烦,也是很多人抱怨的地方。

    实质上knockout已经帮我们想到并处理了这个问题。ko.toJS方法就是官方提供的一个专门用来转换ViewModel的辅助API,它可以自动将监控对象转为属性对象。同时ko还提供了一个ko.toJSON方法,它会将ViewModel直接转换为model的json字符串形式。那么我们定义一个json对象,它的值就是viewModel转为json字符串展示在页面上,让我们可以即时的看到页面发生变化时实体对象同时跟随发生的变化。

//实体对象生成的字符串,并来在页面上同步展示View发生的变化
this.json = ko.computed(function () {
    return ko.toJSON(model.entity);
});

页面ViewModel

<div id="case" data-bind="with:entity" style="padding-left:25px;">
    <div>
        <label>名称:</label>     
        <input data-bind="value: name" />           
    </div>
    <div>
        <label>子级:</label>
        <ul style="display:inline-block">
            <!-- ko foreach:children -->
            <li data-bind="text:$data"></li>
            <!-- /ko -->
            <li>
                <input data-bind="value:$root.newChildName" />
                <input data-bind="click:$root.addChildEventHandle" type="button" value="增加" />
            </li>
        </ul>
    </div>
    <div style="margin-top:50px;">
        <label>json:</label>
        <label data-bind="text:$root.json"></label>
    </div>
</div>

绑定页面视图

var model = new viewModel();

model.entity({
    name: '张三',
    children: [
        '狗子',
        '二蛋'
    ]
});

ko.applyBindings(model, document.getElementById('case'));

完整示例代码

下载