knockoutjs视频教程中的隐藏属性是哪一个

KnockoutJs
javascript(2)
一.背景:在使用knockout搭建前端MVVM框架时,我们往往需要维护如下三个层次的数据结构或者模板
1.server side (Model Provider) :为了业务数据的存取,和数据一致,我们需要在服务端维护一系列可以对json进行增删改查的API,这里以MongoDB为例,通过API存取的对象是mongodb里的一个json文档.
{userName:'aa',email:''}
2.View Model:我们在js模块中定义一个viewModel对象,这个对象应该可以接收后端API返回的json的各个字段,并使用ko去定义需要的数据变化跟踪和数据关联和联动。
var vm = {user:{userName:ko.observable(),email:ko.observable()}};
var user = {js object from backen api};
vm.user.userName(user.userName);
vm.user.email(user.email);
3.html template(View):我们将vm中的字段通过data-bind绑定到页面,这样页面上的数据更新就和vm里的数据就可以双向同步了.
User Name:&input data-bind='value:userName' /&
Email:&input data-bind='value:email' /&
二.问题:我们找到了KOMapper这样一个工具,它能帮助自动根据api获取到的json去生成viewModel,我们在给viewModel添加业务需要的跟踪和联动,当然,komapper生成的viewModel能直接绑定到页面。但是,具体的使用情况和不适用komapper的对比如下:
1.json只有一层结构,根节点需要双向绑定
1.1 业务数据模型:
xxDetail:&&,
yyDetail:&&,
zzDetail:&&
1.2 数据和vm的mapping
var vm = koMapper.fromJS(data);
1.3 vm和template的绑定
&input data-bind=&value:xxDetail& /&
&input data-bind=&value:yyDetail& /&
KOMapper省去了,vm的预定义,省去了各个字段的赋值操作,减少了一层定义就减少了工作量和错误率,节省了时间。
2.json包含Array节点,Array的成员的根节点需要绑定
2.1 业务数据模型
offeringId:&000-&,
offering:&xx&,
comment:&yy&
2.2&数据和vm的mapping
var mapping = {
'content': {
$key: 'offeringId',
$itemOptions: {
'offeringId': 'copy',//不需要observable的属性
'offering': 'copy',
$type: KOLocationTarget,
//成员需要处理之后适应页面绑定,如该行增加提示信息(如:info,但该字段对业务来说数据模型不需要),增加对于改行数据的动态验证信息(如:isValidated);
var vm = koMapper .fromJS(data,mapping);
2.3&vm和template的绑定
&!—ko:foreach:content--&
&a data-bind=&attr:{title:$}&&&/a&
&span data-bind=&text:offering&&&/span&
&span data-bind=&if:!isValidated&&
Please check…&/span&
&!--/ko--&
对于Array的绑定,我们需要定义如2.2所示的handler去告诉KOMapper如何去生成vm对象.
3 json层次较深而且包含根节点需要被绑定和中间节点需要绑定的情况
3.1 业务数据模型
coreTeam:{
bidMgr:{//该节点需要obserable,
name:&&,//该节点不需要obserable
3.2&数据和vm的mapping
针对上述结构中的bidMgr,这是我项目中遇到的一个情况,我们有一个people控件去处理{name:'',email''}这样的对象,其实{name:'',email''}这样的对象就作为一个数据单元存在,如果对其中的name或者email进行observable,这样只会增加ko的运算量和内存消耗,也会增加我们people控件中对observable
节点的unwrap等处理,这就增加了许多多余的或者还是有害的observable节点。所以如果使用KOMapper,我们需要跳过一些不必要呗observe的节点。 从而关心我们的业务和功能真正需要检测和双向绑定的对象。
类似的需求还有:data:{docs:[{name:'',title:'',url:''},{name:'',title:'',url:''}]},这样的数据中,其实只需要将docs绑定到页面上的table中.
mapping= {
$default: 'skipSomeNode',//必须要写handler,因为在整个data下边,我们只需要bidMgr这个节点被observe,coreTeam,ams不需要observe。
koMapper.handlers.skipSomeNode = {
fromJS: function(node, options) {
var nodesNeedSkip = ['coreTeam', 'extendTeam', 'ams', 'apj', 'emea', 'primary', 'other'],
handleKOMap = function (node, nodesToSkip, options) {
var needSkip = false,
temp = {};
for (var child in node) {
if (nodesToSkip.indexOf(child)!== -1) {
needSkip = true;
if (needSkip) {
for (var child in node) {
temp[child] = koMapper.fromJS(node[child], options);
return temp;
for (var child in node) {
if(node[child] instanceof Array){
temp[child] = ko.observable(node[child]);//这个时候需要用 ko.observable(),因为我们只需要对bidMgr这个节点进行绑定。
return temp;
return handleKOMap(node,nodesNeedSkip,options);
&td style=&text-align:left&&&people
params=&{people:$component.data['coreTeam']['ams']['bidMgr']}&&//该组件需要展示user的name和email,需要根据email去站点拿其他用户信息。
&/people&&/td&
到这里,这样复杂程度的业务数据,KOMapper就很不实用,而且增加了handler设计的工作量和错误风险,而且业务数据根据需求变化时,需要重新设计更复杂的handler.
4. 其他情况
如果使用了koMapper,我们其实也有必要在前端template中预绑定一个数据模型和后端一样但数据都是默认值的viewModel,这样在ajax去异步取到后端数据之前,我们的页面才不会空。 总之即使使用了koMapper,前端也必须有一份结构一样的viewModel,因为当前我们后端得到的数据中可能不存在我们前端的业务所需的文档,所以如果最起先的数据产生是从前端发起的,预定义viewModel也是必须的。一旦后端有了数据,在后端数据取到并mapping完毕,产生的mapperViewModel再去替换前端默认的viewModel,这时候ko要去重新做一次绑定
1.下面情况建议使用KOMapper:
1.1 数据从后端发起
1.2 业务数据模型层次较少
1.3 不存在大量的中间节点才需要被observable的对象
2.KOMapper的思想
根据后端取到的数据来生成viewModel,这样就只需要页面上的绑定和API提供的json结构对应。
3.不适用KOMapper,就和文章开头所说,后端提供Model,js 模块定义viewModel,template做绑定.
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:120次
排名:千里之外KnockoutJS Documentation-扩展监控属性
(window.slotbydup=window.slotbydup || []).push({
id: '2611110',
container: s,
size: '240,200',
display: 'inlay-fix'
您当前位置: &
[ 所属分类
| 时间 2015 |
作者 红领巾 ]
ko的监控属性提供了一个基本且必须的特性:读写属性值并在值变化时通知订阅者。一些场景中可能希望为监控属性添加额外的功能。例如为监控属性添加额外的属性,在写入监控属性之前拦截并插入一个可写计算监控属性。ko提供了一个简单而灵活的方式来扩展监控属性。
创建扩展器
ko.extenders
对象添加一个方法来创建一个扩展器。添加的方法有两个参数,第一个参数监控属性自身,第二个参数是任意的参数。它可以返回监控属性本身,或者返回使用原监控属性的计算监控属性。
例如,定义一个扩展器
,订阅监控属性,使用配置的信息在控制台中输出日志:
ko.extenders.logChange = function(target, option) {
target.subscribe(function(newValue) {
console.log(option + ": " + newValue);
使用该扩展器时,调用监控属性的
方法,传入一个包含
属性的对象作为参数。
this.firstName = ko.observable("Bob").extend({logChange: "first name"});
例1:强制输入为数字
&p&&input data-bind="value: myNumberOne" /& (round to whole number)&/p&
&p&&input data-bind="value: myNumberTwo" /& (round to two decimals)&/p&
ko.extenders.numeric = function(target, precision) {
//create a writable computed observable to intercept writes to our observable
var result = ko.pureComputed({
read: target,
//always return the original observables value
write: function(newValue) {
var current = target(),
roundingMultiplier = Math.pow(10, precision),
newValueAsNum = isNaN(newValue) ? 0 : parseFloat(+newValue),
valueToWrite = Math.round(newValueAsNum * roundingMultiplier) / roundingM
//only write if it changed
if (valueToWrite !== current) {
target(valueToWrite);
//if the rounded value is the same, but a different value was written, force a notification for the current field
if (newValue !== current) {
target.notifySubscribers(valueToWrite);
}).extend({ notify: 'always' });
//initialize with current value to make sure it is rounded appropriately
result(target());
//return the new computed observable
function AppViewModel(one, two) {
this.myNumberOne = ko.observable(one).extend({ numeric: 0 });
this.myNumberTwo = ko.observable(two).extend({ numeric: 2 });
ko.applyBindings(new AppViewModel(221.25));
注意,为了自动清除界面上的格式不对的值,需要对计算监控属性调用
extend({ notify: 'always' })
,否则可能会出现用户输入了无效的
后在截断时返回了未改变的
valueToWrite
。然后,由于模型值没变,就不会通知文本框更新。使用
extend({ notify: 'always' })
会强制文本框更新值,即使计算属性的值没变。
例2:为监控属性添加验证
本例创建一个可以验证监控属性的扩展器。不同于返回新对象,该扩展器只是为已有的监控属性添加额外的子监控属性。由于监控属性是函数,它们可以有自己的属性。然而当视图模型转换为json时,子监控属性会被忽略。这样能很方便地添加只跟UI相关不需要与服务器交互的额外功能。
&p data-bind="css: { error: firstName.hasError }"&
&input data-bind='value: firstName, valueUpdate: "afterkeydown"' /&
&span data-bind='visible: firstName.hasError, text: firstName.validationMessage'& &/span&
&p data-bind="css: { error: lastName.hasError }"&
&input data-bind='value: lastName, valueUpdate: "afterkeydown"' /&
&span data-bind='visible: lastName.hasError, text: lastName.validationMessage'& &/span&
ko.extenders.required = function(target, overrideMessage) {
//add some sub-observables to our observable
target.hasError = ko.observable();
target.validationMessage = ko.observable();
//define a function to do validation
function validate(newValue) {
target.hasError(newValue ? false : true);
target.validationMessage(newValue ? "" : overrideMessage || "This field is required");
//initial validation
validate(target());
//validate whenever the value changes
target.subscribe(validate);
//return the original observable
function AppViewModel(first, last) {
this.firstName = ko.observable(first).extend({ required: "Please enter a first name" });
this.lastName = ko.observable(last).extend({ required: "" });
ko.applyBindings(new AppViewModel("Bob","Smith"));
同时应用多个扩展器
在一次调用
方法时可以同时应用多个扩展器。
this.firstName = ko.observable(first).extend({ required: "Please enter a first name", logChange: "first name" });
参考文献:
KnockoutJS Documentation
本文前端(javascript)相关术语:javascript是什么意思 javascript下载 javascript权威指南 javascript基础教程 javascript 正则表达式 javascript设计模式 javascript高级程序设计 精通javascript javascript教程
转载请注明本文标题:本站链接:
分享请点击:
1.凡CodeSecTeam转载的文章,均出自其它媒体或其他官网介绍,目的在于传递更多的信息,并不代表本站赞同其观点和其真实性负责;
2.转载的文章仅代表原创作者观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,本站对该文以及其中全部或者部分内容、文字的真实性、完整性、及时性,不作出任何保证或承若;
3.如本站转载稿涉及版权等问题,请作者及时联系本站,我们会及时处理。
登录后可拥有收藏文章、关注作者等权限...
未长夜痛哭者,不足与语人生
手机客户端
,专注代码审计及安全周边编程,转载请注明出处:http://www.codesec.net
转载文章如有侵权,请邮件 admin[at]codesec.netKnockoutJS学习笔记03:KonckoutJS监视属性 - 起飞网
KnockoutJS中一个非常重要的概念就是observable(监视属性)。 observable有两种,一种是监视属性,一种是监视数组。 ko.observable 我们在中已经看到了如何监视属性的代码:var viewModel = function (firstName, lastName) {
this.firstName = ko.observable(firstName);
this.lastName = ko.observable(lastName);
this.fullName = ko.computed(function () {
return this.firstName() + " " + this.lastName();
如果不使用ko监视会怎么样呢?当一个属性不被ko监视的时候,这个属性的绑定是单次、单向的,即只能完成第一次绑定,之后属性值发生改变将不会更新到界面中,界面中发生的改变也不会影响到属性的值。
只用当这个属性是被监视的时候,才会完成双向的绑定。
ko.observableArray
ko可以监视一个数组的改变。var data = {
item: ["a", "b"]
var viewModel = function (data) {
this.item = ko.observableArray(data.item);
this.selItem = ko.observableArray([]);
this.newItem = ko.observable("");
this.addNew = function () {
if (!this.newItem())
this.item.push(this.newItem());
this.newItem("");
this.removeItem = function () {
this.item.removeAll(this.selItem());
this.selItem([]);
this.sort = function () {
this.item.sort();
ko.applyBindings(new viewModel(data));
代码中,我们使用ko.abservableArray监视一个数组;数组可以用在foreach绑定中,或者select的options属性的绑定中。
这段代码对应的视图如下:新增:&input type="text" data-bind="value: newItem, valueUpdate: 'afterkeydown'" /&
&input type="button" value="添加" data-bind="enable: newItem().length & 0, click: addNew" /&
&select multiple="multiple" style="width: 200px;" data-bind="options: item, selectedOptions:selItem"&&/select&
&input type="button" value="删除" data-bind="click: removeItem" /&
&input type="button" value="排序" data-bind="click: sort" /&
界面如下:
在这个视图中,我们将item数组绑定了select列表的options。
上面的两种监视都是双向绑定的,也就是说无论是数据还是界面发生改变,都会进行界面或数据的更新。另外一种情况是我们只在界面中用到一个属性,这个属性是通过其他属性的值计算出来的,例如我们第一篇中的fullName属性,这个时候我们需要使用ko.computed方法。
<puted方法创建一个计算得来的属性,当视图模型中的值发生改变的时候,这个属性都会被重新计算,并且更新对应的界面的值。代码如下:this.fullName = ko.computed(function () {
return this.firstName() + " " + this.lastName();
总结一下这篇文章的内容:如果要进行双向绑定,就需要使用监视属性,可以通过ko.observable监视一个字段,也可以通过ko.observableArray监视一个数组。如果是通过计算得来的属性,则需要使用ko.computed来监视。
KnockoutJS
KnockoutJS教程MVVM架构~knockoutjs系列之Mapping插件为对象添加ko属性 - 张占岭 - 推酷
MVVM架构~knockoutjs系列之Mapping插件为对象添加ko属性 - 张占岭
对于一个JS对象来说,如果希望将所有属性进行监视,在之前我们需要一个个对属性添加ko.observable方法,而有了Mapping插件后,它可以帮助我们这件事.
在Mapping出现之前
var data={
serverTime:ko.observable( ''),
numUsers: ko.observable(3),
realUsers: ko.observable(3),
我们需要对data对象里所有属性添加ko.observable方法,才可以对它进行监视.
Mapping出现之后
假设有这样一个场景,我们在对象里的realUsers需要跟随numUsers进行变化,这时,我们使用Mapping进行对象的KO处理,然后再使用ko.computed方法进行绑定,看一下代码
  var data = {
serverTime: '',
numUsers: 3,
realUsers: 3,
var M = ko.mapping.fromJS(data);//data对象里所有属性添加ko属性
M.realUsers = ko.computed(function () {
return M.numUsers() ? M.numUsers() * 2 : 0;
ko.applyBindings(M, document.getElementById(&model2&));
对应的HTML代码如下
&div id=&model2&&
&input type=&text& data-bind=&value:serverTime& /&
&input type=&text& data-bind=&value:numUsers,valueUpdate: 'afterkeydown'& /&
&input type=&text& data-bind=&value:realUsers& /&
通过这个例子,让我们知道如何快速的为JS对象添加KO属性,呵呵.
已发表评论数()
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见
正文不准确
标题不准确
排版有问题
主题不准确
没有分页内容
图片无法显示
视频无法显示
与原文不一致

我要回帖

更多关于 knockoutjs angularjs 的文章

 

随机推荐