-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathjquery-dataview.html
568 lines (548 loc) · 27.5 KB
/
jquery-dataview.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
<html>
<head>
<meta charset="utf-8">
<title>jquery-dataview 数据视图</title>
<style>
h3,h4,h5,h6 {
font-size: 1em;
}
pre {
border-left: 1px solid #ccc;
margin: 0 1em;
padding: 0 0.5em;
tab-size:4;
}
code {
font-family: "Courier New";
padding: 0px 3px;
display: inline-block;
}
.toc {
margin: 2em;
}
.toc p {
margin: 0.3em 0;
}
.block {
border-bottom: 1px solid #ccc;
}
</style>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<h1>jquery-dataview 数据视图</h1>
<div>最后更新:2019-02-18</div>
<div id="menu">
<h2>Modules</h2>
<div class="toc">
<p><a href="#jquery-dataview">jquery-dataview (module)</a></p>
</div><hr>
<h2>Keywords</h2>
<div class="toc">
<p><a href="#$.fn.dataview">$.fn.dataview (fn)</a></p>
<p><a href="#$.fn.dataview">$.fn.dataview (alias)</a></p>
<p><a href="#$.fn.dataview.defaults">$.fn.dataview.defaults (var)</a></p>
<p><a href="#$parent">$parent (var)</a></p>
<p><a href="#$this">$this (var)</a></p>
<p><a href="#dv-do">dv-do (key)</a></p>
<p><a href="#dv-else">dv-else (key)</a></p>
<p><a href="#dv-elseif">dv-elseif (key)</a></p>
<p><a href="#dv-for">dv-for (key)</a></p>
<p><a href="#dv-format">dv-format (key)</a></p>
<p><a href="#dv-if">dv-if (key)</a></p>
<p><a href="#dv-on">dv-on (key)</a></p>
<p><a href="#dv-show">dv-show (key)</a></p>
<p><a href="#getData">getData (fn)</a></p>
<p><a href="#jquery-dataview">jquery-dataview (module)</a></p>
<p><a href="#this">this (key)</a></p>
<p><a href="#version">version (fn)</a></p>
</div><hr>
</div>
<div class="block">
<h2 id="jquery-dataview">@module jquery-dataview 数据视图</h2><div class="toc"><p style="margin-left:0em"><a href="#jquery-dataview-1 为DOM对象填充数据">1 为DOM对象填充数据</a></p>
<p style="margin-left:0em"><a href="#jquery-dataview-2 为模板填充数据">2 为模板填充数据</a></p>
<p style="margin-left:0em"><a href="#jquery-dataview-3 计算属性">3 计算属性</a></p>
<p style="margin-left:0em"><a href="#jquery-dataview-4 属性格式化显示">4 属性格式化显示</a></p>
<p style="margin-left:0em"><a href="#jquery-dataview-5 访问子对象">5 访问子对象</a></p>
<p style="margin-left:0em"><a href="#jquery-dataview-6 循环创建、条件创建、条件显示">6 循环创建、条件创建、条件显示</a></p>
<p style="margin-left:2em"><a href="#jquery-dataview-6.1 条件分支">6.1 条件分支</a></p>
<p style="margin-left:2em"><a href="#jquery-dataview-6.2 含有子对象数组时重新绑定数据">6.2 含有子对象数组时重新绑定数据</a></p>
<p style="margin-left:2em"><a href="#jquery-dataview-6.3 通用代码执行 dv-do">6.3 通用代码执行 dv-do</a></p>
<p style="margin-left:0em"><a href="#jquery-dataview-7 指定事件">7 指定事件</a></p>
<p style="margin-left:0em"><a href="#jquery-dataview-8 获取数据">8 获取数据</a></p>
<p style="margin-left:0em"><a href="#jquery-dataview-9 多层嵌套的数据">9 多层嵌套的数据</a></p>
<p style="margin-left:0em"><a href="#jquery-dataview-10 允许多个DOM绑定同一数据">10 允许多个DOM绑定同一数据</a></p>
<p style="margin-left:0em"><a href="#jquery-dataview-11 常见错误">11 常见错误</a></p>
<p style="margin-left:0em"><a href="#jquery-dataview-12 已知问题">12 已知问题</a></p>
<p style="margin-left:0em"><a href="#jquery-dataview-13 多个dataview对象">13 多个dataview对象</a></p>
</div>
<p>jquery插件,用于对DOM进行数据填充与更新,也很适合根据DOM模板创建对象。</p>
<p>特点:</p>
<ul>
<li>允许人为精准控制更新区域,可以更新dataview对象或其任意子对象</li>
<li>对多层次数据支持良好,可对子对象数组用dv-for标签展开,并自动绑定到子对象数据。</li>
</ul>
<h4 id="jquery-dataview-1 为DOM对象填充数据">1 为DOM对象填充数据</h4>
<p>例:对一个DOM赋值</p>
<p>HTML:</p>
<pre><code class="language-html"> <div class="customer">
<p>id=<span name="id"></span></p>
<p>name=<span name="name"></span></p>
</div></code></pre>
<p>JS填充数据:</p>
<pre><code class="language-javascript"> var customer = { id: 1001, name: "SAP AG" };
$(".customer").dataview(customer);</code></pre>
<p class="key"><strong>@key <a id="this">this</a></strong> </p>
<p>递归遍历所有带name属性的结点,如<code><span name="id"></span></code>会用<code>customer.id</code>为其赋值。<br />
特别地,name为"this"时表示数据本身。</p>
<p>版本1.1起, 以"dv-"开头的类名, 与设置<code>name</code>属性具有相同效果, 如<code><span class="dv-id"></span></code>与上例相同.</p>
<p>JS修改数据后,可无参数调用dataview来刷新显示:</p>
<pre><code class="language-javascript"> customer.name = "SAP China";
$(".customer").dataview();</code></pre>
<p>也可为重新绑定数据,如:</p>
<pre><code class="language-javascript"> var customer2 = { id: 1002, name: "Daca Tec" };
$(".customer").dataview(customer2);</code></pre>
<p>TODO: 含有dv-if结点重新绑定数据会有问题,可换成dv-show。</p>
<p>取DOM绑定的数据:</p>
<pre><code class="language-javascript"> var data = $(".customer").dataview('getData');</code></pre>
<p>上面是调用getData方法的形式,在文档中表示为</p>
<pre><code>@fn getData()</code></pre>
<p>如果有参数,则加到调用名后面。</p>
<h4 id="jquery-dataview-2 为模板填充数据">2 为模板填充数据</h4>
<p>HTML:</p>
<pre><code class="language-html"> <div id="divCustomers"></div>
<style type="text/template" id="tplCustomer">
<div class="customer">
<p>id=<span name="id"></span></p>
<p>name=<span name="name"></span></p>
</div>
</style></code></pre>
<p>JS:</p>
<pre><code class="language-javascript"> var customers = [
{ id: 1001, name: "SAP AG" },
{ id: 2001, name: "Oracle CO" }
];
var jtplCustomer = $($("#tplCustomer").html());
var jparent = $("#divCustomers");
$.each(customers, function (i, customer) {
jtplCustomer.clone()
.dataview(customer)
.appendTo(jparent);
});</code></pre>
<h4 id="jquery-dataview-3 计算属性">3 计算属性</h4>
<p>在JS中通过<code>props</code>选项指定属性的计算函数。</p>
<p>HTML:</p>
<pre><code class="language-html"> <div class="customer">
<p>id=<span name="id"></span></p>
<p>fullname=<span name="fullname"></span></p>
</div></code></pre>
<p>JS: 定义fullname属性</p>
<pre><code class="language-javascript"> var customer = { id: 1001, name: "SAP AG" };
var opt = {
props: {
fullname: function () {
// this表示当前层次数据
return this.id + " - " + this.name;
}
}
};
$(".customer").dataview(customer, opt);
// 更新:
customer.name = "SAP China";
$(".customer").dataview();
// fullname也得到更新.</code></pre>
<p>在初始化时,做为计算属性的函数会自动添加到相应的数据上。<br />
在更新视图时,如果发现name属性指定的是一个函数,则以调用后的值来填充。</p>
<h4 id="jquery-dataview-4 属性格式化显示">4 属性格式化显示</h4>
<p class="key"><strong>@key <a id="dv-format">dv-format</a></strong> </p>
<p>在JS中通过<code>formats</code>选项指定属性的格式化函数。</p>
<p>HTML:</p>
<pre><code class="language-html"> <div class="order">
<p>创建日期:<span name="createTm" dv-format="dateD"></span></p>
<p>结束日期:<span name="endTm" dv-format="dateD"></span></p>
<p>总时长:<span name="endTm" dv-format="interval"></span></p>
</div></code></pre>
<p>JS: 定义format函数</p>
<pre><code class="language-javascript"> var order = { id: 1001, createTm: "2017/01/03 10:20:30", endTm: "2017/01/10 18:20:30" };
// 先为属性转换格式
order.createTm = new Date(order.createTm);
order.endTm = new Date(order.endTm);
var opt = {
formats: {
dateD: function (val) {
return val.getFullYear() + "/" + (val.getMonth()+1) + "/" + val.getDate();
},
interval: function (val) {
// this表示当前层次数据
return Math.round((this.endTm - this.createTm) / (1000*3600*24)) + "天";
}
}
};
var jo = $(".order").dataview(order, opt);
order.endTm = new Date("2017/01/11 18:20:30");
// 局部更新
jo.find("[name=endTm][dv-format=interval]").dataview(); // “总时长”显示已更新,“结束日期”显示未更新
// 全部更新
jo.dataview(); // endTm与interval均被更新.</code></pre>
<p>(v1.2) 如果是多处都使用,设置缺省格式更方便,例如定义"num"格式(该格式缺省提供,不必再定义,此处仅用于举例):</p>
<pre><code class="language-javascript"> $.extends($.fn.dataview.defaults.formats, {
num: function (val) {
if (val == null)
return 0;
return parseFloat(val);
}
});</code></pre>
<p>上例中,显示"总时长"也可用计算字段实现,且更加合理,如</p>
<pre><code class="language-html"> <p>总时长:<span name="interval"></span></p></code></pre>
<pre><code class="language-javascript"> var opt = {
formats: ...,
props: {
interval: function () {
// this表示当前层次数据
return Math.round((this.endTm - this.createTm) / (1000*3600*24)) + "天";
}
}
};</code></pre>
<h4 id="jquery-dataview-5 访问子对象">5 访问子对象</h4>
<p>假如有数据:</p>
<pre><code class="language-javascript"> var customer = {
id: 1001,
name: "SAP AG",
addr: {country: "CN", city: "Shanghai"}
};</code></pre>
<p>这里<code>addr</code>是<code>customer</code>的子对象,可以这样来显示<code>customer.addr.city</code>:</p>
<pre><code class="language-html"> <span name="addr.city"></span></code></pre>
<p>求值时,以 <code>eval("data." + name)</code> 的方式获得值。(未使用with机制计算以免降低性能)</p>
<h4 id="jquery-dataview-6 循环创建、条件创建、条件显示">6 循环创建、条件创建、条件显示</h4>
<p class="key"><strong>@key <a id="dv-for">dv-for</a></strong> </p>
<p class="key"><strong>@key <a id="dv-if">dv-if</a></strong> </p>
<p class="key"><strong>@key <a id="dv-show">dv-show</a></strong> </p>
<p>子对象数组可以以<code>dv-for</code>属性来指定循环展开,每复制一个DOM,都会绑定数据到相应的子对象上。</p>
<p>dv-if及dv-show属性:根据该属性的值计算是否保留该结点,或显示该结点。</p>
<p>例:使用dv-for, dv-if, dv-show等标签:</p>
<p>HTML:</p>
<pre><code class="language-html"> <div id="divCustomers">
<div dv-for="customers" dv-if="id>=1000" class="customer">
<li>
<span dv-show="id<=2000">id=<span name="id"></span></span>
name=<span name="name"></span>
</li>
</div>
</div></code></pre>
<p>JS:</p>
<pre><code class="language-javascript"> var data = {
customers: [
{ id: 1, name: "Olive CO" },
{ id: 1001, name: "SAP AG" },
{ id: 2001, name: "Oracle CO" }
]
};
$("#divCustomers").dataview(data);</code></pre>
<p>结果:</p>
<ul>
<li>dv-for指定了用于循环的数组数据,由data.customers数组总共生成两项,id=1的那项因不满足dv-if="id>1000"的条件没有创建。</li>
<li>dv-show指定了显示出来的条件,因而id=2001的项未显示出id。</li>
</ul>
<p><code>dv-for</code>可以在顶层出现,这时dataview返回的是一个新的DOM数组,与传入的jo会不同。</p>
<pre><code class="language-javascript"> jo1 = jo.dataview(data); // jo1与jo可能不同。</code></pre>
<p>如果数据本身就是个数组,可以用<code>dv-for="this"</code>来标识数据:</p>
<pre><code class="language-html"> <div dv-for="this" class="customer">
</div></code></pre>
<p>JS:</p>
<pre><code class="language-javascript"> var customers = [
{ id: 1, name: "Olive CO" },
{ id: 1001, name: "SAP AG" },
{ id: 2001, name: "Oracle CO" }
];
$(".customer").dataview(customers);</code></pre>
<p>特别地,name为"this"时表示数据本身,示例:</p>
<p>HTML:</p>
<pre><code class="language-html"> <div class="customers" dv-for="this">
<span name="this"></span>
</div></code></pre>
<p>或者更简单地:</p>
<pre><code class="language-html"> <div class="customers" dv-for="this" name="this"></div></code></pre>
<p>JS填充数据:</p>
<pre><code class="language-javascript"> var customers = ["SAP AG", "Daca Tec"];
$(".customers").dataview(customers);</code></pre>
<p>dv-if及dv-show属性中指定一个条件表达式,它可以比name中指定的内容要复杂,它的计算原理是:</p>
<pre><code class="language-javascript"> with(data) { eval(val); }</code></pre>
<h5 id="jquery-dataview-6.1 条件分支">6.1 条件分支</h5>
<p class="key"><strong>@key <a id="dv-elseif">dv-elseif</a></strong> </p>
<p class="key"><strong>@key <a id="dv-else">dv-else</a></strong> </p>
<p>除<code>dv-if</code>外,还可以使用<code>dv-elseif</code>, <code>dv-else</code>。</p>
<p>HTML:</p>
<pre><code class="language-html"> <div dv-for="this" id="divStatus">
<p dv-if="status=='YES'">已同意</p>
<p dv-elseif="status=='NO'">已拒绝</p>
<div dv-else>
<input type="button" dv-on="btnYesNo_click" data-status="YES" value="同意">
<input type="button" dv-on="btnYesNo_click" data-status="NO" value="拒绝">
</div>
</div></code></pre>
<p>JS:</p>
<pre><code class="language-javascript"> var data = [
{ status: 'YES' },
{ status: 'NO' },
{ status: 'NEW' },
]
$("#divStatus").dataview(data);</code></pre>
<p>注意:</p>
<ul>
<li>
<p>同一组标签必须用在同一层次的DOM上。下例中<code>dv-if</code>和<code>dv-else</code>不在同一层次上,最终结果是<code>dv-else</code>总会显示。</p>
<pre><code><p dv-if="status=='YES'">已同意</p>
<div><p dv-else>已拒绝</p></div></code></pre>
</li>
<li>在同一层上,<code>dv-if</code>可以多次出现。对每项均重新计算。支持嵌套,即<code>dv-if</code>等标签也可以多次出现在不同层次中。</li>
</ul>
<h5 id="jquery-dataview-6.2 含有子对象数组时重新绑定数据">6.2 含有子对象数组时重新绑定数据</h5>
<p>其原理是:<br />
对于dv-for结点,在展开后,展开结点会删除dv-for属性,加上dv-expanded属性,值为当前数据在数组中的index(从0开始)。<br />
此外,会添加一个隐藏的span标签,其中保存了原始的dv-for结点,用于重新绑定数据时再展示子对象数组。</p>
<p>注意:</p>
<ul>
<li>
<p>子对象数组如果更改(例如有push添加一行),无法更新,必须重新绑定。</p>
<pre><code>data.customers.push({id: 99, name: "cust 99"});
// $("#divCustomers").dataview(); // 这样无法更新
$("#divCustomers").dataview(data, opt); // 需要重新绑定</code></pre>
</li>
<li>
<p>顶层不可以是dv-for结点。示例:</p>
<pre><code><div class="customer_orders">
<ul class="order" dv-for="this">
<li name="dscr"></li>
</ul>
</div></code></pre>
<p>绑定数据及更新示例:</p>
<pre><code>var orders = [{dscr: 'order1'}, {dscr: 'order2'}];
var jo = $(".customer_orders"); // 应避免顶层是dv-for结点。
jo.dataview(orders); // 如果jo是$(".order"),下面就没法更新了。
orders.push({dscr: 'order3'});
jo.dataview(orders);</code></pre>
</li>
</ul>
<h5 id="jquery-dataview-6.3 通用代码执行 dv-do">6.3 通用代码执行 dv-do</h5>
<p>(版本1.1)</p>
<p class="key"><strong>@key <a id="dv-do">dv-do</a></strong> </p>
<p class="var"><strong>@var <a id="$this">$this</a></strong> </p>
<p>在dv-show, dv-if, dv-do这些属性中, 可以执行JS代码, 且可以用<code>$this</code>变量代表当前DOM对象的jQuery包装.<br />
(注意, 写在dv-do这些属性的代码,this变量默认为Window,而非DOM对象)</p>
<p>示例,设置属性、样式等:</p>
<pre><code>jo.dataview({color:'red', imgUrl:'http://server/1.jpg'});</code></pre>
<p>HTML:</p>
<pre><code><p dv-do="$this.css('color', color)"></p>
<img dv-do="$this.attr('src', imgUrl)"></img></code></pre>
<p>这类似于Vue的<code>v-bind:src=""</code>或者<code>:src=""</code>操作,然而更加灵活。</p>
<p>示例2:以下两种设置的效果等价</p>
<pre><code><p dv-show="name=='LJ'"></p>
<p dv-do="$this.toggle(name=='LJ')"></p></code></pre>
<p>示例3:以下三种设置的效果等价</p>
<pre><code><p name="price"></p>
<p class="dv-price"></p>
<p dv-do="$this.html(price)"></p></code></pre>
<p>在代码中也可以调用计算属性, 但需要加括号, 如以下两行等价:</p>
<pre><code><span class="dv-fullname"></span>
<span dv-do="$this.html(fullname())"></span></code></pre>
<p>JS:</p>
<pre><code>var props = {
fullname: function () { this ... }
};
jo.dataview(data, {props: props});</code></pre>
<h4 id="jquery-dataview-7 指定事件">7 指定事件</h4>
<p class="key"><strong>@key <a id="dv-on">dv-on</a></strong> </p>
<p>在HTML中使用<code>dv-on</code>属性指定事件,在JS中使用选项<code>events</code>与其对应。</p>
<pre><code class="language-html"> <div dv-on="liOrder_click"></div></code></pre>
<p>上面代码定义了<code>jo.on("click", data, liOrder_click)</code>,所有用到的函数必须通过<code>events</code>选项定义:</p>
<pre><code class="language-javascript"> var events = {
liOrder_click: function (ev) {
var order = ev.data; // 等同于 $(this).dataview('getData');
// ...
}
};
jo.dataview(data, {events: events});</code></pre>
<p>可以指定多个事件,用逗号","隔开:</p>
<pre><code class="language-html"> <input dv-on="txtName_change,txtName_keydown"></div></code></pre>
<p>HTML:</p>
<pre><code class="language-html"> <form class="customer" dv-on="frmCustomer_submit">
<p>id=<span name="id"></span></p>
<input dv-on="txtName_change,txtName_keydown" name="name">
<button dv-on="btnUpdate_click">更新</button>
</form></code></pre>
<p>上面为form指定了submit事件,dv-on的值要求是<code>{domName}_{eventName}</code>的格式,domName可任意起名,eventName必须是合法的事件名。</p>
<p>JS:</p>
<pre><code class="language-javascript"> var events = {
frmCustomer_submit: function (ev) {
alert(arguments.callee.name);
console.log("cancel submit");
return false;
},
txtName_change: function (ev) {
alert(arguments.callee.name);
},
txtName_keydown: function (ev) {
console.log(arguments.callee.name);
},
btnUpdate_click: function (ev) {
alert(arguments.callee.name);
}
};
var opt = {
events: events
};
var customer = { id: 1001, name: "SAP AG" };
$(".customer").dataview(customer, opt);</code></pre>
<p>与直接使用onclick属性相比,用dv-on的好处有:</p>
<ul>
<li>事件处理函数不必是全局函数。</li>
<li>事件处理函数的参数<code>ev.data</code>即是DOM绑定的数据,使用很方便。</li>
</ul>
<h4 id="jquery-dataview-8 获取数据">8 获取数据</h4>
<pre><code class="language-javascript"> // 获取DOM关联的数据
var data = jo.dataview('getData');
//TODO:
// 获取用户输入的数据
var formData = jo.dataview('getFormData');
// 获取用户输入的数据与原始数据差异部分。
var formDataDiff = jo.dataview('getFormData', {diff: true});</code></pre>
<h4 id="jquery-dataview-9 多层嵌套的数据">9 多层嵌套的数据</h4>
<p>每个对象数组是一个嵌套层次。</p>
<ul>
<li>可通过数据的 <code>$parent</code> 属性访问上层数据。</li>
<li>支持子对象的计算字段</li>
<li>不必更新根对象,可以指定更新任意子对象的数据视图。</li>
</ul>
<p class="var"><strong>@var <a id="$parent">$parent</a></strong> </p>
<p>示例:数据模型如下:</p>
<pre><code>customer = {id, name, %addr={country, city}, @orders }
@orders = {id, amount, @items={id, name} }</code></pre>
<p>customer是0层,@orders是第1层,@items是第2层; 注意:addr下的字段与customer是当作同一层的。</p>
<p>JS数据:</p>
<pre><code class="language-javascript"> var customer = {
id: 1001,
name: "SAP AG",
addr: {country: "CN", city: "Shanghai"},
orders: [
{id: 1, amount: 9000, items: [
{id: 101, name: "item 101"},
{id: 102, name: "item 102"}
]},
{id: 2, amount: 11000, items: [
{id: 201, name: "item 201"}
]}
]
}</code></pre>
<p>HTML数据视图:</p>
<pre><code class="language-html"> <div class="customer">
<p> name: <span name="name"></span> </p>
<p> addr: <span name="addr.country"></span> / <span name="addr.city"></span> </p>
<ul>
<li dv-for="orders" class="order">
<p>order id=<span name="id"></span>, amount=<span name="amount"></span></p>
<ul>
<li dv-for="items" class="item">
<p>item id=<span name="id"></span></p>
<p>item name=<span name="name"></span></p>
<p>fullname=<span name="fullname"></span></p>
</li>
</ul>
</li>
</ul>
</div></code></pre>
<p>注意:</p>
<ul>
<li>可以使用<code>addr.country</code>的格式指定数据源。</li>
</ul>
<p>JS:</p>
<pre><code class="language-javascript"> var itemOpt = {
props: {
fullname: function () {
var order = this.$parent;
var customer = order.$parent;
return customer.name + " - " + this.name;
}
}
};
var orderOpt = {
children: {items: itemOpt}
};
var customerOpt = {
children: {orders: orderOpt}
};
$(".customer").dataview(customer, customerOpt);
// 局部更新:只更新一个item
customer.orders[0].items[0].name += " - updated";
$(".customer .order:first .item:first").dataview();
// 只更新一个order:
++ customer.orders[0].amount;
customer.orders[0].items[0].name += " - updated2";
$(".customer .order:first").dataview();
// 全部更新
$(".customer").dataview();</code></pre>
<p>注意:</p>
<ul>
<li>在为多层嵌套数据设置选项时,如果某层未指定opt,可使用上一层的的选项。如果指定了opt,则上一层的选项无效。<br />
因而,假如上一层指定了opt={formats: ...},在本层未指定opt时,可以使用上层的formats,而如果本层指定了opt={events: ...},则上层指定的那些formats无法使用。</li>
</ul>
<h4 id="jquery-dataview-10 允许多个DOM绑定同一数据">10 允许多个DOM绑定同一数据</h4>
<p>(v1.2)</p>
<pre><code class="language-html"><p class="userInfo">id=<span name="id"></span></p>
...
<p class="userInfo">name=<span name="name"></span></p></code></pre>
<pre><code class="language-javascript">jpage.find(".userInfo").dataview(userInfo);</code></pre>
<h4 id="jquery-dataview-11 常见错误">11 常见错误</h4>
<p>生成的DOM有混乱:常常由标签未闭合导致</p>
<h4 id="jquery-dataview-12 已知问题">12 已知问题</h4>
<p>当有多层数据时,直接设置数据中的子对象,无法更新。</p>
<pre><code>var data = { a: 'aa', b: [{id: 100}] };
jo.dataview(data, opt);
// 无法更新
data.b = [{id: 200}, {id:300}];
jo.dataview();
// 解决方法
jo.dataview(data); // 重新绑定,效率差。这时不用指定opt, 延用之前的。</code></pre>
<h4 id="jquery-dataview-13 多个dataview对象">13 多个dataview对象</h4>
<p>如果数据对象是分离的,可以设置多个dataview对象:</p>
<pre><code><div>
<div class="user dv-userName"></div>
<div class="card dv-cardNo"></div>
<div class="user dv-userPhone"></div>
<div class="card dv-cardBalance"></div>
</div></code></pre>
<p>JS:</p>
<pre><code>// 更新时直接重绑定
jpage.find("user").dataview({userName:'name', phone:'123'});
jpage.find("card").dataview({cardNo:'12', cardBalance:99});</code></pre>
<p>它比于用 {user: {...}, card: {...}} 来绑定更方便和高效,因为没两个数据不是一起出现的,统一控制较麻烦,不如分别绑定。</p></div>
<div class="block">
<h2 id="version">@fn version()</h2>
<p>取版本号:</p>
<pre><code>var ver = jo.dataview("version");</code></pre></div>
<div class="block">
<h2 id="getData">@fn getData(exact?=false, ret?)</h2>
<p>取DOM元素对应的数据。<br />
可对dataview对象或其任意子元素调用该函数,返回该元素所在层次对应的数据。</p>
<p>如果取到的是子数组中的数据,可以通过<code>$parent</code>属性取上层数据。</p>
<pre><code>var data = jo.dataview('getData');
var parentData = data.$parent;</code></pre>
<p class="param"><strong>@param exact</strong> ?=false 查找本结点上的数据,如果没有会继续查找父结点,直到遍历完父结点。设置为true禁止查找父结点。</p>
<p class="param"><strong>@param ret</strong> ? 输出参数,如果传入一个对象,则会设置 {data, jo, opt} 其中data与返回值一致。jo为包含data的结点,可能是当前结点或其父结点等,opt为该结点上设置的选项。</p></div>
<div class="block">
<h2 id="$.fn.dataview">@fn $.fn.dataview(data, opt?)</h2>
<p class="alias"><strong>@alias <a id="$.fn.dataview">$.fn.dataview</a></strong> (method, param1, ...)</p>
<p class="param"><strong>@param opt=</strong> {props, events}</p>
<p>由模板创建DOM,填充数据,绑定事件,数据更新后再调用可刷新DOM显示。支持多层次的数据。</p>
<p>返回处理后的结点集合。</p>
<p>注意:</p>
<ul>
<li>只有顶层或dv-for标签(子对象数组)的DOM上会直接绑定数据。</li>
<li>初始化后,dv-for, dv-if属性会被删除。dv-show仍保留,可根据条件显示隐藏对象。</li>
</ul></div>
<div class="block">
<h2 id="$.fn.dataview.defaults">@var $.fn.dataview.defaults</h2>
<p>设置全局缺省选项。</p>
<p class="see"><strong>@see <a href="#$.fn.dataview">$.fn.dataview</a></strong> 参考opt参数说明。</p></div>
<div style="text-align:center">Generated by jdcloud-gendoc</div>
</body>
</html>