FineUI 官方论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

本论坛已关闭(禁止注册、发帖和回复)
请移步 三石和他的朋友们

FineUI首页 WebForms - MVC & Core - JavaScript 常见问题 - QQ群 - 十周年征文活动

FineUI(开源版) 下载源代码 - 下载空项目 - 获取ExtJS - 文档 在线示例 - 版本更新 - 捐赠作者 - 教程

升级到 ASP.NET Core 3.1,快、快、快! 全新ASP.NET Core,比WebForms还简单! 欢迎加入【三石和他的朋友们】(基础版下载)

搜索
查看: 1853|回复: 1

FineUI + Knockout 实现数据绑定 2

[复制链接]
发表于 2020-3-31 18:53:51 | 显示全部楼层 |阅读模式
本帖最后由 棕榈 于 2020-3-31 18:50 编辑

FineUI + Knockout 实现数据绑定 2






上一篇我基于Knockout实现了基本的数据绑定,这里我将采用Knockout实现FineUI控件的添加及删除,这里的示例只是用于演示,FineUI的Grid完全可以实现示例的效果。


FineUI中控件及布局都是通过JS来实现的,并且都有自己的DOM结构,直接用Knockout基于DOM进行操作是无法实现的,我在原先 knockout-fineui.js 基础上增加一个新的绑定 'ui', 可以直接用它来创建控件,代码:

  1. <div data-bind="ui:{options:{type:'numberbox',width:100}, value:$data.count}"></div>
复制代码

这里的 options 属性就是创建控件的参数,参数详情可以查看FineUIJS的API文档,后面的 value 与上一篇的数据绑定参数是一致的。这样就可以采用 Knockout中的foreach,if,ifnot等绑定来实现控件添加及删除。

虽然实现了控件的操作,但同时也失去了FineUI中提供的布局功能,由于所生成的控件都是独立于布局容器的,所以也无法通过布局容器进行布局,只能通过CSS来完成相应的布局。但在实际的使用中也发现,采用CSS布局并不是这么容易,由于FineUI的控件都有相应的DOM结构,有时需要进行很多层的样式修改才能完成想要的效果。

所以在常规的使用操作中是不推荐这种方式的,这种方式主要用于一些个性化需求及与其它第三方控件结合使用时采用。

下面为示例代码:

  1. @page
  2. @model FineUICore.EmptyProject.RazorPages.Pages.KnockoutModel
  3. @{
  4.     ViewBag.Title = "Knockout";
  5.     var F = @Html.F();
  6. }

  7. @section body {
  8.     <table id="goods" class="table">
  9.         <thead>
  10.             <tr>
  11.                 <td scope="col">#</td>
  12.                 <td scope="col">名称</td>
  13.                 <td scope="col">单位</td>
  14.                 <td scope="col">数量</td>
  15.                 <td scope="col">单价</td>
  16.                 <td scope="col">合计</td>
  17.                 <td scope="col">操作</td>
  18.             </tr>
  19.         </thead>
  20.         <tbody>
  21.             <!-- ko foreach: goodsList -->
  22.             <tr>
  23.                 <td scope="row"><span data-bind="text:$index()+1"></span></td>
  24.                 <td>
  25.                     <div data-bind="ui:{options:{type:'dropdownlist',data:$parent.goodsNames,width:100}, value:$data.name}"></div>
  26.                 </td>
  27.                 <td>
  28.                     <div data-bind="ui:{options:{type:'dropdownlist',data:$parent.goodsUnits,width:100}, value:$data.unit}"></div>
  29.                 </td>
  30.                 <td>
  31.                     <div data-bind="ui:{options:{type:'numberbox',width:100}, value:$data.count}"></div>
  32.                 </td>
  33.                 <td>
  34.                     <div data-bind="ui:{options:{type:'numberbox',width:100}, value:$data.unitPrice}"></div>
  35.                 </td>
  36.                 <td>
  37.                     <div data-bind="ui:{options:{type:'label',width:60}, text:'¥'+$data.totalPrice()}"></div>
  38.                 </td>
  39.                 <td>
  40.                     <div data-bind="ui:{options:{type:'button', text:'删除商品'}, click:function(){$parent.goodsList.remove($data)}}"></div>
  41.                 </td>
  42.             </tr>
  43.             <!-- /ko -->
  44.             <tr>
  45.                 <td colspan="6" style="text-align:right">总价</td>
  46.                 <td><span data-bind="text:'¥'+total()"></span></td>
  47.             </tr>
  48.         </tbody>
  49.     </table>

  50.     <f:Panel Title="Knockout" ContentEl="#goods" BodyPadding="15" IsFluid="true">
  51.         <Toolbars>
  52.             <f:Toolbar>
  53.                 <Items>
  54.                     <f:Button Text="添加商品" AttributeDataTag="f:{click:add}"></f:Button>
  55.                     <f:Button Text="生成JSON" AttributeDataTag="f:{click:json}"></f:Button>
  56.                 </Items>
  57.             </f:Toolbar>
  58.         </Toolbars>
  59.     </f:Panel>
  60.     <br />
  61.     <h5 data-bind="visible:goodsList().length>0">商品JSON</h5>
  62.     <div data-bind="text:goodsJson,visible:goodsList().length>0"></div>
  63. }

  64. @section script {
  65.     <script src="~/knockout-3.5.1/knockout.js"></script>
  66.     <script src="~/res/js/knockout-fineui.js"></script>

  67.     <script>
  68.         F.ready(function () {
  69.             $('[data-tag]').each(function () {
  70.                 $(this).attr('data-bind', $(this).data('tag'));
  71.             });

  72.             function Goods() {
  73.                 var self = this;
  74.                 self.name = ko.observable('1');
  75.                 self.unit = ko.observable('1');
  76.                 self.count = ko.observable(1);
  77.                 self.unitPrice = ko.observable(3450);
  78.                 self.totalPrice = ko.pureComputed(function () {
  79.                     return self.unitPrice() * self.count();
  80.                 });
  81.             };

  82.             function ViewModel() {
  83.                 var self = this;

  84.                 self.goodsNames = [
  85.                     ['1', '台式电脑'],
  86.                     ['2', '笔记本'],
  87.                     ['3', '硬盘'],
  88.                     ['4', '内存条'],
  89.                     ['5', '光盘']
  90.                 ];

  91.                 self.goodsUnits = [
  92.                     ['1', '台'],
  93.                     ['2', '块'],
  94.                     ['3', '条'],
  95.                     ['4', '个'],
  96.                     ['5', '张']
  97.                 ];

  98.                 self.goodsList = ko.observableArray();
  99.                 self.goodsJson = ko.observable();

  100.                 self.total = ko.pureComputed(function () {
  101.                     var total = 0;
  102.                     for (var goods of self.goodsList()) {
  103.                         total += goods.totalPrice();
  104.                     }
  105.                     return total;
  106.                 });

  107.                 self.add = function () {
  108.                     self.goodsList.push(new Goods());
  109.                 }

  110.                 self.json = function () {
  111.                     self.goodsJson(ko.toJSON(self.goodsList));
  112.                 };
  113.             };

  114.             ko.applyBindings(new ViewModel());
  115.         });
  116.     </script>
  117. }
复制代码



示例项目文件请到知识星球下载




本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
发表于 2020-4-1 06:32:09 | 显示全部楼层
开启了一种无限可能性,等于打开了fineUI与MVVM一扇大门!
期待三石老大在这个基础加上层支持.这FineUI就更厉害了!!!

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|FineUI 官方论坛 ( 皖ICP备2021006167号-1 )

GMT+8, 2024-3-29 03:53 , Processed in 0.046668 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表