精华内容
下载资源
问答
  • VUE数据绑定方法
    千次阅读
    2020-08-04 14:37:35

    Vue 框架很核心的功能就是双向的数据绑定。 双向是指:HTML 标签数据 绑定到 Vue 对象,另外反方向数据也是绑定的。通俗点说就是,Vue 对象的改变会直接影响到 HTML 的标签的变化,而且标签的变化也会反过来影响 Vue 对象的属性的变化。
    这样以来,就彻底变革了之前 Dom 的开发方式,之前 Dom 驱动的开发方式尤其是以 jQuery 为主的开发时代,都是 dom 变化后,触发 js 事件,然后在事件中通过 js 代码取得标签的变化,再跟后台进行交互,然后根据后台返回的结果再更新 HTML 标签,异常的繁琐。有了 Vue 这种双向绑定,让开发人员只需要关心 json 数据的变化即可,Vue 自动映射到 HTML 上,而且 HTML 的变化也会映射回 js 对象上,开发方式直接变革成了前端由数据驱动的 开发时代,远远抛弃了 Dom 开发主导的时代了。

    一、Vue 绑定文本:

    数据绑定最常见的形式就是使用 “Mustache” 语法(双大括号)的文本插值,比如模板引擎:handlebars 中就是用的{{}}。创建的 Vue 对象中的 data 属性就是用来绑定数据到 HTML 的。如:

    <span>Message: {{ msg }}</span>
    <script>
      var app = new Vue({         // 创建Vue对象。Vue的核心对象。
        el: '#app',               // el属性:把当前Vue对象挂载到 div标签上,#app是id选择器
        data: {                   // data: 是Vue对象中绑定的数据
          msg: 'Hello Vue!'   // message 自定义的数据
        }
      });
    </script>

    对于所有的数据绑定, Vue.js 都提供了完全的 JavaScript 表达式支持。

    1、简单的拼接:

    <span>Message: {{ msg + ' - ' + name }}</span>
    <script>
      var app = new Vue({         // 创建Vue对象。Vue的核心对象。
        el: '#app',               // el属性:把当前Vue对象挂载到 div标签上,#app是id选择器
        data: {                   // data: 是Vue对象中绑定的数据
          msg: 'Hi',              // message 自定义的数据
          name: 'flydragon'       // name自定义的属性,vue可以多个自定义属性,属性类型也可是复杂类型
        }
      });
    </script>
    Hi - flydragon

    2、计算、函数处理:

    <td>{{ user.name=== '' ? '-' : user.name.subString(0,5) }}</td>
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>Vue入门之数据绑定-表达式运算</title>
      <script src="https://unpkg.com/vue/dist/vue.js"></script>
    </head>
    <body>
      <div id="app">
        {{ msg + ' - ' + name }}
        <p>
          {{ isOk ? '123' : '456' }}
        </p>
        <p>我的年龄是: {{ age *2 }}</p>
      </div>
    
      <script>
      var app = new Vue({         // 创建Vue对象。Vue的核心对象。
        el: '#app',               // el属性:把当前Vue对象挂载到 div标签上,#app是id选择器
        data: {                   // data: 是Vue对象中绑定的数据
          msg: 'Hi',              // message 自定义的数据
          name: 'flydragon',
          isOk: true,
          age: 18
        }
      });
      </script>
    </body>
    </html>
     <template v-if="user">
                   <div>{{formatDate(user.updateTime)}}</div>
               
     </template>
    
    methods:{
       formatDate(dateTime) {
          if (!dateTime) return '';
          return parseTime(dateTime);
        },
    }

     3、计算属性:

    在做数据的绑定的时候,数据要进行处理之后才能展示到 html 页面上,虽然 vue 提供了非常好的表达式绑定的方法,但是只能应对低强度的需求。比如: 把一个日期按照规定格式进行输出,可能就需要我们对日期对象做一些格式化的出来,表达式可能就捉襟见肘了。Vue 对象提供的 computed 属性,可以让我们开发者在里面可以放置一些方法,协助我们绑定数据操作,这些方法可以跟 data 中的属性一样用,注意这些方法用的时候不要加()。 如:

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>Vue入门之htmlraw</title>
      <script src="https://unpkg.com/vue/dist/vue.js"></script>
    </head>
    <body>
      <div id="app">
        <table>
          <tr>
            <!-- computed里面的函数可以直接当成data里面的属性用,非常方便,注意没有括号!!!-->
            <td>生日</td><td>{{ getBirthday }}</td>
          </tr>
          <tr>
            <td>年龄</td><td>{{ age }}</td>
          </tr>
          <tr>
            <td>地址</td><td>{{ address }}</td>
          </tr>
        </table>
      </div>
      <script>
        var app = new Vue({
          el: '#app',
          data: {
            birthday: 914228510514,     // 这是一个日期对象的值:1998年11月1日
            age: 19,
            address: '北京昌平区龙泽飞龙'
          },
          computed: {
            // 把日期换成 常见规格格式的字符串。
            getBirthday: function () {
              var m = new Date(this.birthday);
              return m.getFullYear() + '年' + m.getMonth() +'月'+ m.getDay()+'日';
            }
          }
        });
      </script>
    </body>
    </html>

    4、数据绑定过滤器:

    {{ message | filterA | filterB }}

    在这个例子中,filterA 被定义为接收单个参数的过滤器函数,表达式 message 的值将作为参数传入到函数中。然后继续调用同样被定义为接收单个参数的过滤器函数 filterB,将 filterA 的结果传递到 filterB 中。

    过滤器是 JavaScript 函数,因此可以接收参数:

    {{ message | filterA('arg1', arg2) }}

    这里,filterA 被定义为接收三个参数的过滤器函数。其中 message 的值作为第一个参数,普通字符串 'arg1'作为第二个参数,表达式 arg2 的值作为第三个参数。

     二、Vue 绑定html标签属性:

       Vue 中不能直接使用{{ expression }} 语法对 html 的标签属性进行绑定,而是用它特有的 v-bind 指令。语法结构:

    <标签 v-bind:html标签属性名="要绑定的Vue对象的data里的属性名"></标签>

    属性绑定简写:由于v-bind 使用非常频繁,所以 Vue 提供了简单的写法,可以去掉 v-bind 直接使用:即可。如

    <div v-bind:id="MenuContaineId">等价于<div :id="MenuContaineId">

    1、简单的属性绑定:

    <span v-bind:id="menuId">{{ menuName }}</span>
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>Vue入门之数据绑定--属性绑定</title>
      <script src="https://unpkg.com/vue/dist/vue.js"></script>
    </head>
    <body>
      <div id="app">
        <div v-bind:id="MenuContaineId">
          <a href="#" v-bind:class="MenuClass">首页</a>
          <a href="#" v-bind:class="MenuClass">产品</a>
          <a href="#" v-bind:class="MenuClass">服务</a>
          <a href="#" v-bind:class="MenuClass">关于</a>
        </div>
      </div>
    
      <script>
        var app = new Vue({
          el: '#app',
          data: {                   // data: 是Vue对象中绑定的数据
            MenuClass: 'top-menu',
            MenuContaineId: 'sitemenu'
          }
        });
      </script>
    </body>
    </html>

    2、布尔类型值用于属性绑定:标签的布尔类型的特性(属性),比如: disabled特性。这类属性特点只要存在就表示 truev-bind 应用于这类属性的时候,如果绑定值为真,则输出挣钱的对应属性。如果为假值,则不会渲染此特性。

    <button v-bind:disabled="isButtonDisabled">按钮</button>

    如果 isButtonDisabled 的值是 nullundefined 或 false,则 disabled 特性甚至不会被包含在渲染出来的 <button> 元素中。 如果为真值:<button disabled="disabled">按钮</button>。

    3、样式绑定:对于普通的属性的绑定,只能用上面的讲的绑定属性的方式。而 Vue 专门加强了 class 和 style 的属性的绑定。可以有复杂的对象绑定、数组绑定样式和类。:class = "{className1:条件1,className2:条件2}",其中,className可以加上'',也可以不加引号。

    例1: 

    <div id="app">
        <div v-bind:id="MenuContaineId" v-bind:class="{ active: isActive }">
          绑定颜色类
        </div>
      </div>
    
      <script>
        var app = new Vue({
          el: '#app',
          data: {                   // data: 是Vue对象中绑定的数据
            MenuContaineId: 'menu',
            isActive: true
          }
        });
      </script>
    

    例2: 

    <div id="app">
      <div class="static"
         v-bind:class="{ active: isActive, 'text-danger': hasError }">
      </div>
    </div>
    <script>
      var app = new Vue({
        el: '#app',
        data: {          // data: 是Vue对象中绑定的数据
          isActive: true,
          hasError: false
        }
      });
    </script>

     结果:

    <div id="app">
      <div class="static active">
      </div>  
    </div>

    例3:

    <div id="app">
      <div class="static"
         v-bind:class="classObject">
      </div>
    </div>
    <script>
      var app = new Vue({
        el: '#app',
        data: {
          classObject: {
            active: true,
            'text-danger': false
          }
        }
      });
    </script>

    结果:

    <div id="app">
      <div class="static active">
      </div>
    </div>

    例4:

    <template>
      <div>
        <div>
          <el-select v-model="editSatus" placeholder="请选择">
            <el-option
              v-for="item in options"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            ></el-option>
          </el-select>
        </div>
     
        <div>
          <el-form>
            <el-input
              v-model="redtext"
              :class="{'my-disabled':(editSatus === false)}"
            ></el-input>
          </el-form>
     
          <div v-for=" item in colors" :key="item">
                 <span  :class="{'mytrue':(obj[`my${item}Change`] === 1),myred:(item === 'redtext')}">{{item}}</span>
                
          </div>
     
          
        </div>
      </div>
    </template>
     
    <script>
    export default {
      data() { 
        return {
            colors:['redtext','greentext','yellowtext'],
          redtext: "redtext",
          greentext: "greentext",
          yellowtext: "yellowtext",
          myredtextChange:1,
          obj:{ myredtextChange:1,
          mygreentextChange:0},
          //是否可以编辑,默认可以
          editSatus: true,
          options: [
            {
              value: true,
              label: "编辑"
            },
            {
              value: false,
              label: "查看"
            }
          ]
        };
      },
      methods: {
          getText(item){
              let val = 'my'+item+'Change';
             
              
              return this.obj.myredtextChange;
          }
      }
    };
    </script>
    <style lang="scss">
    .my-disabled {
      pointer-events: none;
    }
    .myred {
        color:  red;
      .ivu-input.ivu-input-default {
        color: red;
      }
      .ivu-select.ivu-select-single.ivu-select-default {
        color: red;
      }
      textarea {
        color: red;
      }
      .ivu-form-item-label {
        color: red;
      }
    }
    .mytrue{
        font-style:oblique
    }
    </style>

     例5:删除某行页面上以中划线表示并字体标红:

    <el-table-column label="项目合同金额">
                  <template slot-scope="scope">
                    <span
                      :style="{color:(scope.row.status==2) ? 'red' : '#007bd9',
                          'text-decoration': (scope.row.status==2) ? 'line-through' : 'none'}"
                    >{{scope.row.projectMoney}}</span>
                  </template>
                </el-table-column>

    例6:

     <div
                  class="exam-calendar"
                  :class="getClassName(examDayMap[data.day].length)"
                  v-if="examDayMap[data.day] && examDayMap[data.day].length > 0"
                >
                  <div @mouseenter="showDrawer(data.day)" class="exam-name">
                    <span> {{ examDayMap[data.day].length + '个考试' }}</span>
                  </div>
                </div>
    
    
    
    methods:{
     getClassName(examCount) {
          if (examCount >= 5) {
            return 'red';
          } else if ((examCount < 5) & (examCount >= 3)) {
            return 'orange';
          } else if (examCount < 3) {
            return 'blue';
          }
        }
    }
    
    
    .exam-calendar {
        margin-top: 5px;
        display: flex;
        justify-content: center; /* 水平方向 居中*/
        align-items: center; /* 垂直方向 居中*/
        color: #fff;
        background-color: #f1c98d;
        border-color: #f1c98d;
        border-radius: 15px;
        padding: 8px;
        cursor: pointer;
      }
      .red {
        background-color: red;
        border-color: red;
      }
      .blue {
        background-color: blue;
        border-color: blue;
      }

     

    4、绑定样式数组:

    <div v-bind:class="[activeClass, errorClass]">

    data: {
      activeClass: 'active',
      errorClass: 'text-danger'
    }

    5、内联样式绑定:内联样式的绑定,非常类似于样式类的操作。v-bind:style 的对象语法十分直观——看着非常像 CSS ,其实它是一个 JavaScript 对象。 CSS 属性名可以用驼峰式(camelCase)或短横分隔命名(kebab-case)。v-bind:style会自动添加前缀,即当 v-bind:style 使用需要特定前缀的 CSS 属性时,如 transform ,Vue.js 会自动侦测并添加相应的前缀。

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>Vue入门之htmlraw</title>
      <script src="https://unpkg.com/vue/dist/vue.js"></script>
    </head>
    <body>
      <div id="app">
        <div v-bind:style="{fontSize: size + 'px', backgroundColor: bgcolor, width: width}">
          vue 入门系列教程
        </div>
      </div>
      <script>
        var app = new Vue({
          el: '#app',
          data: {
            size: 19,
            width: 200,
            bgcolor: 'red'
          }
        });
      </script>
    </body>
    </html>

    5、数据绑定过滤器写法:

    <!-- 在双花括号中 -->
    {{ message | capitalize }}
    
    <!-- 在 `v-bind` 中 -->
    <div v-bind:id="rawId | formatId"></div>

     你可以在一个组件的选项中定义本地的过滤器

    filters: {
      capitalize: function (value) {
        if (!value) return ''
        value = value.toString()
        return value.charAt(0).toUpperCase() + value.slice(1)
      }
    }

    或者在创建 Vue 实例之前全局定义过滤器:

    Vue.filter('capitalize', function (value) {
      if (!value) return ''
      value = value.toString()
      return value.charAt(0).toUpperCase() + value.slice(1)
    })
    
    new Vue({
      // ...
    })

     

    三、输出纯html:

    由于 Vue 对于输出绑定的内容做了提前 encode,保障在绑定到页面上显示的时候不至于被 xss 攻击。但某些场景下,我们确保后台数据是安全的,那么我们就要在网页中显示原生的 HTML 标签。Vue 提供了v-html指令。

    <div id="app">
      <div v-bind:id="MenuContaineId" v-html="MenuBody">
      </div>
    </div>
    <script>
      var app = new Vue({
        el: '#app',
        data: {                   // data: 是Vue对象中绑定的数据
          MenuContaineId: 'menu',
          MenuBody: '<p>这里是菜单的内容</p>'
        }
      });
    </script>

    结果:

    <div id="app">
      <div id="menu">
        <p>这里是菜单的内容</p>
      </div>
    </div>

    四、双向绑定:以上均为单向绑定。双向绑定指令为v-model:

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>Vue入门之htmlraw</title>
      <script src="https://unpkg.com/vue/dist/vue.js"></script>
    </head>
    <body>
      <div id="app">
        <!-- v-model可以直接指向data中的属性,双向绑定就建立了 -->
        <input type="text" name="txt" v-model="msg">
        <p>您输入的信息是:{{ msg }}</p>
      </div>
      <script>
        var app = new Vue({
          el: '#app',
          data: {
            msg: '双向数据绑定的例子'
          }
        });
      </script>
    </body>
    </html>

    最终的结果就是:你改变 input 文本框的内容的时候,p 标签中的内容会跟着进行改变。

    1、双向绑定的修饰符:

    (1).lazy

    在默认情况下,v-model 在每次 input 事件触发后将输入框的值与数据进行同步 (除了上述输入法组合文字时)。你可以添加 lazy 修饰符,从而转变为使用 change 事件进行同步:

    <!-- 在“change”时而非“input”时更新 -->
    <input v-model.lazy="msg" >

    (2).number

    如果想自动将用户的输入值转为数值类型,可以给 v-model 添加 number 修饰符:

    <input v-model.number="age" type="number">

    (3).trim:

    如果要自动过滤用户输入的首尾空白字符,可以给 v-model 添加 trim 修饰符:

    <input v-model.trim="msg">

    2、双向绑定案例:

    (1)文本:

       1)单行文本:

    <div id="example-1">
      <input v-model="message" placeholder="edit me">
      <p>Message is: {{ message }}</p>
    </div>
    <script>
    new Vue({
      el: '#example-1',
      data: {
        message: ''
      }
    })
    </script>

        2)多行文本:

    <div id="example-textarea">
      <span>Multiline message is:</span>
      <p style="white-space: pre-line;">{{ message }}</p>
      <br>
      <textarea v-model="message" placeholder="add multiple lines"></textarea>
    </div>
    <script>
    new Vue({
      el: '#example-textarea',
      data: {
        message: ''
      }
    })
    </script>

       在文本区域插值 (<textarea>{{text}}</textarea>) 并不会生效,应用 v-model 来代替。

    2、复选框:

    <div id="example-3">
      <input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
      <label for="jack">Jack</label>
      <input type="checkbox" id="john" value="John" v-model="checkedNames">
      <label for="john">John</label>
      <input type="checkbox" id="mike" value="Mike" v-model="checkedNames">
      <label for="mike">Mike</label>
      <br>
      <span>Checked names: {{ checkedNames }}</span>
    </div>
    <script>
    new Vue({
      el: '#example-3',
      data: {
        checkedNames: []
      }
    })
    </script>

    3、单选按钮:

    <div id="example-4">
      <input type="radio" id="one" value="One" v-model="picked">
      <label for="one">One</label>
      <br>
      <input type="radio" id="two" value="Two" v-model="picked">
      <label for="two">Two</label>
      <br>
      <span>Picked: {{ picked }}</span>
    </div>
    <script>
    new Vue({
      el: '#example-4',
      data: {
        picked: ''
      }
    })
    </script>

     4、选择框:

       1)单选:

    <div id="example-5">
      <select v-model="selected">
        <option disabled value="">请选择</option>
        <option>A</option>
        <option>B</option>
        <option>C</option>
      </select>
      <span>Selected: {{ selected }}</span>
    </div>
    <script>
    new Vue({
      el: '#example-5',
      data: {
        selected: ''
      }
    })
    </script>

    如果 v-model 表达式的初始值未能匹配任何选项,select 元素将被渲染为“未选中”状态。在 iOS 中,这会使用户无法选择第一个选项。因为这样的情况下,iOS 不会触发 change 事件。因此,更推荐像上面这样提供一个值为空的禁用选项。

    下拉框值回显问题:需要值和类型一致,如:以下isMultipleProject=1,回显不了,因为isMultipleProject值为整形,而下拉框value值为字符型,

    <el-select
                      v-model="isMultipleProject"
                      placeholder="请选择"
                      :disabled="updateDisable"
                    >
                      <el-option value="1" label="多产品"></el-option>
                      <el-option value="0" label="单产品"></el-option>
                    </el-select>

    可以把下拉框值改成整形,:value表示整数型:

     <el-option :value=1 label="多产品"></el-option>
                      <el-option :value=0 label="单产品"></el-option>

     

      2)多选:绑定到数组

    <div id="example-6">
      <select v-model="selected" multiple style="width: 50px;">
        <option>A</option>
        <option>B</option>
        <option>C</option>
      </select>
      <br>
      <span>Selected: {{ selected }}</span>
    </div>
    <script>
    new Vue({
      el: '#example-6',
      data: {
        selected: []
      }
    })
    </script>

    3)远程搜索下拉:回显不需要加载列表,常用于下拉列表数据量较大的场景。

    <template>
      <el-select
        v-model="value"
        multiple
        filterable
        remote
        reserve-keyword
        placeholder="请输入关键词"
        :remote-method="remoteMethod"
        :loading="loading">
        <el-option
          v-for="item in options"
          :key="item.value"
          :label="item.label"
          :value="item.value">
        </el-option>
      </el-select>
    </template>
    <script>
      export default {
        data() {
          return {
            options: [],
            value: [],
            list: [],
            loading: false,
            states: ["Alabama", "Alaska", "Arizona", "Washington", "West Virginia"]
          }
        },
        mounted() {
          this.list = this.states.map(item => {
            return { value: `value:${item}`, label: `label:${item}` };
          });
        },
        methods: {
          remoteMethod(query) {
            if (query !== '') {
              this.loading = true;
              setTimeout(() => {
                this.loading = false;
                this.options = this.list.filter(item => {
                  return item.label.toLowerCase()
                    .indexOf(query.toLowerCase()) > -1;
                });
              }, 200);
            } else {
              this.options = [];
            }
          }
        }
      }
    </script>

    更多案例详见官网https://element.eleme.cn/#/zh-CN/component/installation

    更多相关内容
  • C#的各种数据绑定

    2019-01-17 12:07:45
    该文档介绍了各种窗体数据绑定 WPF/WinForm 自定义DataViewManger 数据游标 ListView的数据绑定 属性通知的事件绑定 AOP实现的数据绑定 WPF的超简洁的集合数据绑定 SQLserver的数据库增删改查绑定实例
  • WPF xaml数据绑定

    2020-09-09 22:08:09
    xaml数据绑定xaml数据绑定xaml数据绑定xaml数据绑定xaml数据绑定xaml数据绑定xaml数据绑定xaml数据绑定xaml数据绑定xaml数据绑定xaml数据绑定xaml数据绑定
  • 相信大家百度了很多Echarts如何从后台获取数据进行绑定的demo都没有满意的结果。经过自己的理解,这份文档详细的解释了Echarts怎么从后台获取数据进行绑定。从后台返回json格式字符串,然后转换自己想要的数据,希望...
  • 数据绑定的简单介绍 在执行程序时,Spring MVC会根据客户端请求参数的不同,将请求消息中的信息以一定的方式转换并绑定到控制器类的方法参数中。这种将请求消息数据与后台方法参数建立连接的过程就是Spring MVC中的...

    数据绑定的简单介绍

    在执行程序时,Spring MVC会根据客户端请求参数的不同,将请求消息中的信息以一定的方式转换并绑定到控制器类的方法参数中。这种将请求消息数据与后台方法参数建立连接的过程就是Spring MVC中的数据绑定。

    数据绑定的完成操作

    在数据绑定过程中,Spring MVC框架会通过数据绑定组件(DataBinder)将请求参数串的内容进行类型转换,然后将转换后的值赋给控制器类中方法的形参,这样后台方法就可以正确绑定并获取客户端请求携带的参数了。
    在这里插入图片描述

    1. Spring MVC将ServletRequest对象传递给DataBinder;
    2. 将处理方法的入参对象传递给DataBinder;
    3. DataBinder调用ConversionService组件进行数据类型转换、数据格式化等工作,并将ServletRequest对象中的消息填充到参数对象中;
    4. 调用Validator组件对已经绑定了请求消息数据的参数对象进行数据合法性校验;
    5. 校验完成后会生成数据绑定结果BindingResut对象,Spring MVC会将BindingResult对象中的内容赋给处理方法的相应参数。

    简单的数据绑定

    在先前的注释实现Spring MVC当中进行修改:参考:Spring MVC 的核心类和注释实现MVC程序

    当前端请求的参数比较简单时,可以在后台方法的形参中直接使用Spring MVC提供的默认参数类型进行数据绑定。如下所示:

    • HttpServletRequest:通过request对象获取请求信息;
    • HttpServletResponse:通过response处理响应信息;
    • HttpSession:通过session对象得到session中存放的对象;
    • Model/ModelMap:Model是一个接口,ModelMap是一个接口实现,作用是将model数据填充到request域。

    使用以下代码获取前端的数据

    	@RequestMapping(value = "/firstController1")
    	public String SelectUser(HttpServletRequest request) {
    		String id = request.getParameter("id");
    		if (id!=null) {
    			System.out.println(id);
    		}
    		return "first";
    	}
    

    运行项目,打开对应的网址,在后面使用问号传递参数 id=78 http://localhost:8080/DataBanding/hello/firstController1?id=78,随后在控制台当中查看。可以看到一条输出语句,打印了id的值。
    在这里插入图片描述
    在这里使用的是HttpServletRequest,当然还可以使用其他的对象:HttpServletResponse、HttpSession、Model/ModelMap不一 一列举。

    当我们的命名比较同意的话就可以不使用到对象进行获取值,直接获取Integer对象的值:

    	@RequestMapping(value = "/firstController2")
    	public String SelectUser1(Integer id) {
    		if (id!=null) {
    			System.out.println("firstController2="+id);
    		}
    		return "first";
    	}
    

    相同的。我们重新传递这个值:http://localhost:8080/DataBanding/hello/firstController2?id=78,很显然这样也是可以的,而且相比之下较为简便。
    在这里插入图片描述
    当使用到的变量名不是特别一致的时候,或者前端请求中参数名和后台控制器类方法中的形参名不一样,那么这样就会导致后台无法正确绑定并接收到前端请求的参数。这要如何实现呢?可以考虑使用Spring MVC提供的@RequestParam注解类型来进行间接数据绑定。@RequestParam注解的属性声明如下:
    在这里插入图片描述
    定义方法,添加@RequestParam即可,如下是给id添加一个别名,user_id

    	@RequestMapping(value = "/firstController3")
    	public String SelectUser3( @RequestParam(value="user_id")Integer id) {
    		if (id!=null) {
    			System.out.println("firstController3/user_id="+id);
    		}
    		return "first";
    	}
    

    调用这个方法传递参数进行测试:http://localhost:8080/DataBanding/hello/firstController3?user_id=78传递的参数是user_id=78,随后在控制台查看输出的id:
    在这里插入图片描述
    绑定POJO类型

    在使用简单数据类型绑定时,可以很容易的根据具体需求来定义方法中的形参类型和个数,然而在实际应用中,客户端请求可能会传递多个不同类型的参数数据,如果还使用简单数据类型进行绑定,那么就需要手动编写多个不同类型的参数,这种操作显然比较繁琐。 针对多类型、多参数的请求,可以使用POJO类型进行数据绑定。POJO类型的数据绑定就是将所有关联的请求参数封装在一个POJO中,然后在方法中直接使用该POJO作为形参来完成数据绑定。其中 POJO(Plain Ordinary Java Object)是指简单的Java对象,实际就是普通JavaBeans。

    .比如:定义一个表单提交,需要提交用户名和密码。register.jsp文件。

    	<form action="${pageContext.request.contextPath }/hello/registerUser"
    		method="post">
    		用户名:<input type="text" name="username" /><br />&nbsp;&nbsp;&nbsp;码:<input type="password" name="password" /><br />
    		<input type="submit" value="注册" />
    	</form>
    

    新定义一个com.lzq.po 的包,在下面新建一个User类,把需要传递的数据进行定义,并且getter/setter封装。在使用POJO类型数据绑定时,前端请求的参数名(指如上form表单内各元素的name属性值)必须与要绑定的POJO类中的属性一样,这样才会自动将请求数据绑定到POJO对象中,否则后台接收的参数值为null。

    	 String username;
    	 Integer password;
    

    随后在前文相同的地方定义路由:

    	@RequestMapping(value = "/toRegister")
    	public String toRegister() {
    		return "register";
    	}
    
    	@RequestMapping(value = "/registerUser")
    	public String toRegisterUser(User user) {
    		String username = user.getUsername();
    		Integer password = user.getPassword();
    		System.out.println("username = " + username + ", password = " + password);
    		return "register";
    	}
    

    由toRegister路由进入,先跳到jsp页面进行输入数据,在jsp当中的action这个属性进行再次跳转,到/registerUser路由,进行接收。并且将数据进行打印输出,http://localhost:8080/DataBanding/hello/registerUser
    在这里插入图片描述
    在控制台当中进行查看:
    在这里插入图片描述
    但是在这里,会发现当用户名输入中文的时候会导致乱码。如何修改呢?我们只需要将编码都设置为utf-8即可,在web.xml文件当中添加代码即可。

    <filter>
            <filter-name>CharacterEncodingFilter</filter-name>		
            <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
            <init-param>
                       <param-name>encoding</param-name>
                       <param-value>UTF-8</param-value>
            </init-param>
    </filter>
    <filter-mapping>
           <filter-name>CharacterEncodingFilter</filter-name>
           <url-pattern>/*</url-pattern>
    </filter-mapping>
    

    上述代码中,通过<filter-mapping>元素的配置会拦截前端页面中的所有请求,并交由名称CharacterEncodingFilter 的编码过滤器类进行处理 filter 元素中,首先配置了编码过滤器类org.spring.framework.web.filter.CharacterEncodingFilter,然后通过初始化参数设置统一的编码为 UTF-8 这样所有的请求信息内容都会以 UTF-8 的编码格式进行解析。再进行测试,输入中文,在控制台进行查看:
    在这里插入图片描述
    绑定包装POJO

    在用户查询订单时,页面传递的参数可能包括:订单编号、用户名称等信息,这就包含了订单和用户两个对象的信息,这个时候订单和用户信息混合封装,显得比较混乱。可以使用包装POJO类型绑定。
    所谓的包装POJO,就是在一个POJO中包含另一个简单POJO。例如,在订单对象中包含用户对象。这样在使用时,就可以通过订单查询到用户信息。
    实现如下:首先在com.lzq.po这个包下面定义一个Orders订单类,订单类和用户类存在关联关系,在订单类当中引用用户类并进行封装(封装的代码省略)。如下代码所示:

    	private Integer ordersId;
    	private User user;
    

    这里的orders.jsp页面和user.jsp页面相同,修改跳转的地址即可

    <body>
    	<form action="${pageContext.request.contextPath }/hello/findOrdersWithUser"
    		method="post">
    		订单编号:
    		<input type="text" name="ordersId" /><br /> 
    		所属用户:
    		<input type="text" name="user.username" /><br />
    		<input type="submit" value="查询" />
    	</form>
    </body>
    

    在java类中获取数据:

    	@RequestMapping(value = "/tofindOrdersWithUser")
    	public String tofindOrdersWithUser() {
    		return "orders";
    	}
    
    	@RequestMapping(value = "/findOrdersWithUser")
    	public String findOrdersWithUser(Orders orders) {
    		Integer ordersId = orders.getOrdersId();
    		User user = orders.getUser();
    		String username = user.getUsername();
    		System.out.println("username = " + username + ", ordersId = " + ordersId);
    		return "orders";
    	}
    

    最后点开网址进行测试:http://localhost:8080/DataBanding/hello/findOrdersWithUser
    在这里插入图片描述
    点击查询,在控制台当中就会打印出订单编号和所属用户的数据:
    在这里插入图片描述
    自定义数据的绑定

    有些特殊类型的参数是无法在后台进行直接转换的,例如日期数据就需要开发者自定义转换器( Converter )或格式化( Formatter )来进行数据绑定。

    Converter类
    Spring 框架提供了一个 Converter 用于将一种类型的对象转换为另一种类型的对象 例如,用户输入的曰期形式可能是“2020/05/20 10:15:26”的字符串,而要Spring 将输入的日期与后台的 Date 进行绑定,则需要将字符串转换为日期,此时就可以自定义一个 Converter类来进行曰期转换,自定义 Converter 类需要实现 org.springframework.core.convert.converter.Converter 接口。

    public intface Convert<S,T>{
    	T convert(S source)
    }
    

    S表示源类型,T表示目标类型。示例如下:
    先创建一个com.lzq.convert包。创建一个类实现接口

    package com.lzq.convert;
    
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import org.springframework.core.convert.converter.Converter;
    import jdk.nashorn.internal.parser.DateParser;
    
    public class DataConvert implements Converter<String,Date>{
    	private String DatePattern ="yyyy-MM-dd HH:mm:ss";
    	@Override
    	public Date convert(String source) {
    		SimpleDateFormat sdf = new SimpleDateFormat(DatePattern);
    		try {
    			return sdf.parse(source);
    		} catch (Exception e) {
    			throw new IllegalArgumentException("无效的日期格式: "+ DatePattern);
    		}
    	}
    }
    

    在需要使用到这个转换器,在springmvc-config当中需要定义:
    首先添加了 mvc schema 信息 ;然后定义了组件扫描器和视图解析器;接下来显示装配了自定义的类型转换器;最后编写了自定义类型转换器的配置,其中 Bean的类名称必须为 org.springframework.context.support.ConversionServiceFactoryBean ,并且Bean 申还需要包含一个 converters 属性,通过该属性列出程序中自定义的所有 Converter。

    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="
    	   http://www.springframework.org/schema/mvc
    	   http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
    	   "
    
    	<!-- 显示装配自定义类型转换器 -->
    	<mvc:annotation-driven
    		conversion-service="conversionService" />
    	<!-- 自定义配置 -->
    	<bean id="conversionService"
    		class="org.springframework.context.support.ConversionServiceFactoryBean">
    		<property name="converters">
    			<set>
    				<bean class="com.lzq.convert.DataConvert"></bean>
    			</set>
    		</property>
    	</bean>
    

    使用测试代码

    	@RequestMapping(value = "/customDate")
    	public String CustomDate(Date date) {
    		System.out.println("data = " + date);
    		return "success";
    	}
    

    启动项目输入网址:http://localhost:8080/DataBanding/hello/customDate?date=2020-05-20 10:46:35 在控制台当中查看结果:
    在这里插入图片描述
    Formatter类

    Formatter 和 Converter 的作用相同,只是 Formatter 的源类型必须是一个 String 类型,而 Converter 可以是任意类型 。使用 Formatter 自定义转换器类需要实现 org.springframework.format.Formatter 接口,该接口的代码如下所示。

    public interface Formatter<T> extends Printer<T>, Parser<T> {}
    

    Formatter 接口继承了 Printer Parser 接口,其泛型 表示输入字符串要转换的目标类型 Printer,Parser 接口中,分别包含一个 print(),parse()方法,所有的实现类必须覆盖这两个方法。在前面的包当中创建一个DateFormatter类。

    package com.lzq.convert;
    
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.Locale;
    import org.springframework.format.Formatter;
    
    public class DateFormatter implements Formatter<Date> {
    	String DatePattern = "yyyy-MM-dd HH:mm:ss";
    	private SimpleDateFormat simpledateformat;
    
    	@Override
    	public String print(Date date, Locale locale) {
    		return new SimpleDateFormat().format(date);
    	}
    
    	@Override
    	public Date parse(String source, Locale locale) throws ParseException {
    		simpledateformat = new SimpleDateFormat(DatePattern);
    		return simpledateformat.parse(source);
    	}
    }
    

    DateFormatter 类实现了 Formatter 接口,并实现了接口中的两个方法其中 print() 方法会返回目标对象的字符串,而 parseO 方法会利用指定的 Locale 将一个 String 析成目标类型,要使用 Formatter 自定义的曰期转换器,同样需要在 Spring MVC 的配置文件中进行注册。修改Convert的bean即可。

    	<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
    		<property name="formatters">
    			<set>
    				<bean class="com.lzq.convert.DataFormatter"></bean>
    			</set>
    		</property>
    	</bean>
    

    在使用这个bean的时候,把前面的bean注释一下:使用相同的网址进行测试http://localhost:8080/DataBanding/hello/customDate?date=2020-05-20%2011:11:26,在控制填查看结果
    在这里插入图片描述
    复杂数据类型的绑定

    Spring MVC 的数据绑定(复杂数据绑定——数组与集合)单击前往 ->

    展开全文
  • DevExpress TreeList 数据绑定,很简单,注意KeyFieldName ParentFieldName两个属性设置
  • WPF之数据绑定总结(博客源码)

    热门讨论 2014-02-15 18:07:13
    1.TextBox绑定后台的值(一次绑定,类似于赋值); 2.TextBox绑定后台的值(可通过改绑定的值自动更新值); 3.TextBox绑定另一个控件的属性值(随时更新值); 4.TextBox绑定另一个控件的属性值(双向更新); 5....
  • ASP.NET 数据绑定详解 代码+步骤

    千次阅读 多人点赞 2020-04-29 21:25:14
    数据绑定概述2. 简单数据绑定2.1. 属性绑定2.2. 表达式绑定2.3. 集合绑定2.4. 方法绑定3. 数据控件绑定3.1. ListControl 控件3.2. GridView 控件3.2.2. 使用GridView控件绑定数据源3.2.3. 自定义GridView控件的列...

    1. 数据绑定概述

    数据绑定指的是从数据源获取数据,或者向数据源写入数据。主要有两种形式:简单数据绑定数据控件绑定

    其中简单数据绑定分为属性绑定、表达式绑定、集合绑定和方法绑定;数据控件绑定分为ListControl 控件、GridView 控件、DataList 控件和ListView控件

    2. 简单数据绑定

    2.1. 属性绑定

    基于属性的数据绑定所涉及的属性必须要包含Get访问器,它的基本语法为:

    <%# 属性名称 %>
    

    如果在ASP页面中对属性进行了绑定,那么需要调用Page类的DataBind方法才能执行绑定操作,例如下例:

    // .aspx文件
    <body>
        <form id="form1" runat="server">
            <div>
            	<!-- 数据绑定 -->
                <asp:Label ID="Label1" runat="server" Text="图书名称:"><%# BookName %></asp:Label>
            </div>
            <div>
            	<!-- 数据绑定 -->
                <asp:Label ID="Label2" runat="server" Text="图书价格:"><%# BookPrice %></asp:Label>
            </div>
        </form>
    </body>
    
    // .aspx.cs文件
    // BookName属性
    public string BookName {
        get {
            return "ASP.NET程序设计";
        }
    }
    
    // BookPrice属性
    public string BookPrice {
        get {
            return "49";
        }
    }
    
    protected void Page_Load(object sender, EventArgs e){
        // 调用DataBind()方法执行绑定
        Page.DataBind();
    }
    

    执行结果如下:
    在这里插入图片描述

    2.2. 表达式绑定

    表达式绑定的语法与属性绑定一致,它可以在属性绑定的基础上通过表达式对数据进行处理,它的语法如下:

    <%# 表达式 %>
    

    例如在属性绑定的基础上,要查询10本书的总价格,则代码如下:

    // .aspx文件
    <body>
        <form id="form1" runat="server">
            <div>
            	<!-- 数据绑定 -->
                <asp:Label ID="Label1" runat="server" Text="图书名称:"><%# BookName %></asp:Label>
            </div>
            <div>
            	<!-- 表达式绑定 -->
                <asp:Label ID="Label2" runat="server" Text="图书价格:"><%# Convert.ToInt32(BookPrice)*10 %></asp:Label>
            </div>
        </form>
    </body>
    
    // .aspx.cs文件
    // BookName属性
    public string BookName {
        get {
            return "ASP.NET程序设计";
        }
    }
    
    // BookPrice属性
    public string BookPrice {
        get {
            return "49";
        }
    }
    
    protected void Page_Load(object sender, EventArgs e){
        // 调用DataBind()方法执行绑定
        Page.DataBind();
    }
    

    执行结果如下所示
    在这里插入图片描述

    2.3. 集合绑定

    有一些服务器控件是多记录控件,如DropDownList控件, 这类控件即可使用集合作为数据源对其进行绑定。通常情况下,集合数据源主要包括ArrayList、Hashtabel、 DataView、 DataReader 等。

    例如下面代码,实现了对DropDownList控件进行数据绑定:

    // .aspx文件
    <body>
        <form id="form1" runat="server">
            <div>
                <asp:Label ID="Label1" runat="server" Text="图书名称:"></asp:Label>
                <asp:DropDownList ID="DropDownList1" runat="server"></asp:DropDownList>
            </div>
        </form>
    </body>
    
    protected void Page_Load(object sender, EventArgs e){
        // 构建数据源
        ArrayList arrayList = new ArrayList();
        arrayList.Add("iisexpress");
        arrayList.Add("assembly");
        arrayList.Add("Windows");
    
    	// 指定数据源
        DropDownList1.DataSource = arrayList;
        // 数据绑定
        DropDownList1.DataBind();
    }
    

    执行结果如下:
    在这里插入图片描述

    2.4. 方法绑定

    方法的绑定与属性绑定的语法是一致的,只不过把绑定对象更替为了方法,例如下面的代码:

    // .aspx文件
    <body>
        <form id="form1" runat="server">
            <div>
            	<!-- 数据绑定 -->
                <asp:Label ID="Label1" runat="server" Text="图书名称:"><%# BookName %></asp:Label>
            </div>
            <div>
            	<!-- 方法绑定 -->
                <asp:Label ID="Label2" runat="server" Text="图书价格:"><%# PriceTest("49") %></asp:Label>
            </div>
        </form>
    </body>
    
    // .aspx.cs文件
    public string PriceTest(string _price) {
        return _price;
    }
    
    protected void Page_Load(object sender, EventArgs e){
        // 调用DataBind()方法执行绑定
        Page.DataBind();
    }
    

    执行结果如下:
    在这里插入图片描述

    3. 数据控件绑定

    3.1. ListControl 控件

    ListControl控件用来定义所有列表类型控件的所有属性方法和事件,是一个抽象基类,它能够控制的控件主要包括:DropDownList控件、ListBox控件、CheckBoxList控件、RadioButtonList控件。

    ListControl控件能够指定能够用来填充列表控件的数据源,其中与数据绑定修改的属性有:

    1. DataSource属性,用来设置数据源
    2. DataTextField属性,用来指定提供文本内容的数据源字段
    3. DataValueField属性,用来指定提供值的数据源字段

    例如下面代码,将图书列表以DropDownList控件进行显示,当用户选择了DropDownList控件中的某个值后,页面会进行相应的信息更新。

    // .aspx文件
    <body>
        <form id="form1" runat="server">
            <div>
            	<!-- ListControl控件绑定DropDownList -->
                <asp:Label ID="Label1" runat="server" Text="图书列表:"><%# BookName %></asp:Label>
                <asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="True" OnSelectedIndexChanged="DropDownList1_SelectedIndexChanged"></asp:DropDownList>
            </div>
            <div>
                <asp:Label ID="Label2" runat="server" Text="图书编码:"></asp:Label>
                <asp:Label ID="Label3" runat="server" Text=""></asp:Label>
            </div>
            <div>
                <asp:Label ID="Label4" runat="server" Text="图书名称:"></asp:Label>
                <asp:Label ID="Label5" runat="server" Text=""></asp:Label>
            </div>
        </form>
    </body>
    
    // .aspx.cs文件
    protected void Page_Load(object sender, EventArgs e){
        if (!IsPostBack) {
            SqlConnection sqlConnection = new SqlConnection("Server=DEITIVOD;Database=db_LibraryMS;User Id=sa;pwd=admin");
            SqlDataAdapter sqlDataAdapter = new SqlDataAdapter("select book_code, book_name from tb_bookinfo;", sqlConnection);
    
            // 将查询到的数据放入一个DataSet
            DataSet dataSet = new DataSet();
            sqlDataAdapter.Fill(dataSet);
    
            // 对DropDownList执行指定数据源和数据绑定
            DropDownList1.DataSource = dataSet;
            DropDownList1.DataTextField = "book_name"; // 指定要显示的字段
            DropDownList1.DataValueField = "book_code"; // 指定要绑定的主键值
            DropDownList1.DataBind();
        }
    }
    
    protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e){
        Label3.Text = DropDownList1.SelectedValue;
        Label5.Text = DropDownList1.SelectedItem.Text;
    }
    

    执行效果如下:
    数据库中的tb_bookinfo数据表的数据如下所示:
    在这里插入图片描述

    ASP页面中显示的数据:
    在这里插入图片描述

    3.2. GridView 控件

    GridView控件可称之为数据表格控件,它以表格的形式显示数据源中的数据,每列表示一个字段,而每行表示一条 记录,可以将其理解为数据库技术中的视图。

    3.2.2. 使用GridView控件绑定数据源

    使用GridView控件绑定数据源主要用到

    1. DataSource属性,用来指定数据源
    2. DataBind方法,用来执行数据绑定

    如下代码实现了将SQL Server数据库中的数据通过GridView控件显示到ASP页面中

    // .aspx文件
    <body>
        <form id="form1" runat="server">
            <div>
            	<!-- GridView控件绑定数据源 -->
                <asp:GridView ID="GridView1" runat="server" CellPadding="4" ForeColor="#333333" GridLines="None">
                    <AlternatingRowStyle BackColor="White" ForeColor="#284775" />
                    <EditRowStyle BackColor="#999999" />
                    <FooterStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />
                    <HeaderStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />
                    <PagerStyle BackColor="#284775" ForeColor="White" HorizontalAlign="Center" />
                    <RowStyle BackColor="#F7F6F3" ForeColor="#333333" />
                    <SelectedRowStyle BackColor="#E2DED6" Font-Bold="True" ForeColor="#333333" />
                    <SortedAscendingCellStyle BackColor="#E9E7E2" />
                    <SortedAscendingHeaderStyle BackColor="#506C8C" />
                    <SortedDescendingCellStyle BackColor="#FFFDF8" />
                    <SortedDescendingHeaderStyle BackColor="#6F8DAE" />
                </asp:GridView>
            </div>
        </form>
    </body>
    
    // .aspx.cs文件
     protected void Page_Load(object sender, EventArgs e){
        SqlConnection sqlConnection = new SqlConnection("Server=DEITIVOD;Database=db_LibraryMS;User Id=sa;pwd=admin");
        SqlDataAdapter sqlDataAdapter = new SqlDataAdapter("select * from leaveword;", sqlConnection);
    
        DataSet dataSet = new DataSet();
        sqlDataAdapter.Fill(dataSet);
    
        GridView1.DataSource = dataSet; // 指定数据集
        GridView1.DataBind(); // 执行数据绑定
    }
    

    数据库中leaveword数据表的数据如下所示:
    在这里插入图片描述

    执行效果如下,ASP页面中显示的数据:
    在这里插入图片描述

    3.2.3. 自定义GridView控件的列字段名

    GridView中的数据列分为7种类型

    数据列说明
    BoundFiled最常用的数据列,用来显示文本
    CheckBoxFiled用来显示Boolean值
    CommandFiled用来显示执行选择、编辑和删除操作的命令按钮
    ImageFiled用来显示图片
    HyperLinkFiled用来将数据以超链接的形式显示出来
    ButtonFiled用来为GridView控件创建命令按钮,该按钮可以操作其所在行的数据
    TemplateFiled用来给用户提供自定义类型的数据列

    在VS开发环境中按下面的步骤操作,以BoundFiled 为例将GridView中的字段名修改为中文显示:
    在这里插入图片描述
    如果只想显示我们自定义的列,可以将AutoGenerateColumns设置为False
    在这里插入图片描述上面两张图的内容也可以通过下面的代码实现:

    // .aspx文件
    <body>
        <form id="form1" runat="server">
            <div>
            	<!-- GridView控件绑定数据源,并且自定义列 -->
                <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False">
                    <Columns>
                        <asp:BoundField DataField="title" HeaderText="图书编号" />
                        <asp:BoundField DataField="email" HeaderText="邮箱" />
                        <asp:BoundField DataField="context" HeaderText="内容" />
                    </Columns>
                </asp:GridView>
            </div>
        </form>
    </body>
    
    // .aspx.cs文件
    protected void Page_Load(object sender, EventArgs e){
        SqlConnection sqlConnection = new SqlConnection("Server=DEITIVOD;Database=db_LibraryMS;User Id=sa;pwd=admin");
        SqlDataAdapter sqlDataAdapter = new SqlDataAdapter("select * from leaveword;", sqlConnection);
    
        DataSet dataSet = new DataSet();
        sqlDataAdapter.Fill(dataSet);
    
        GridView1.DataSource = dataSet; // 指定数据集
        GridView1.DataBind(); // 执行数据绑定
    }
    

    效果如下,左边是直接指定数据源时的表格,右边是对列自定义的表格:
    在这里插入图片描述

    3.2.4. 使用GridView控件分页显示数据

    使用GridView控件分页显示数据主要用到了以下两个属性和一个事件:

    1. AllowPaging属性,用来决定是否启用分页功能
    2. PageSize属性,设置分页时每页显示几条记录,默认是12条
    3. PageIndexChanging事件,用来响应用户的页面切换指令

    下图的GridView属性说明了该GridView开启了分页功能,每页是展示3条记录
    在这里插入图片描述下面的代码,在开启分页功能的基础上重写了PageIndexChanging事件,实现了GridView的分页功能:

    // .aspx文件
    <body>
        <form id="form1" runat="server">
            <div>
            	<!-- GridView控件绑定数据源,并且使用分页功能 -->
                <asp:GridView ID="GridView1" runat="server" AllowPaging="True" OnPageIndexChanging="GridView1_PageIndexChanging" PageSize="3">
                </asp:GridView>
            </div>
        </form>
    </body>
    
    // .aspx.cs文件
    protected void Page_Load(object sender, EventArgs e){
    	    SqlConnection sqlConnection = new SqlConnection("Server=DEITIVOD;Database=db_LibraryMS;User Id=sa;pwd=admin");
        SqlDataAdapter sqlDataAdapter = new SqlDataAdapter("select * from leaveword;", sqlConnection);
    
        DataSet dataSet = new DataSet();
        sqlDataAdapter.Fill(dataSet);
    
        GridView1.DataSource = dataSet; // 指定数据集
        GridView1.DataBind(); // 执行数据绑定
    }
    
    protected void GridView1_PageIndexChanging(object sender, GridViewPageEventArgs e){
        // 设置当前页为新页
        GridView1.PageIndex = e.NewPageIndex;
        // 绑定新页数据
        GridView1.DataBind();
    }
    

    执行结果如下:
    在这里插入图片描述

    3.2.5. 选中、编辑和删除GridView数据项

    在ASP.NET中实现选中、编辑和删除GridView数据项

    在这里插入图片描述

    3.3. DataList 控件

    3.3.1. DataList 模板

    DataList控件是一个常用的数据绑定控件,可以称之为迭代控件,该控件能够以某种设定好的模板格式循环显示多条数据,这种模板格式是可以根据需要进行自定义的,比较于GridView控件,虽然GridView控件功能非常强大,但它始终只能以表格的形式显示数据,而使用DataList控件则灵活性非常强,其本身就是一个富有弹性的控件。

    DataList中一共有以下几种模板:

    模板说明
    ItemTemplate为项提供内容
    AlternatingltemTemplate为交替项提供内容,是ItemTemplate的扩展
    SelectedltemTemplate为当前选定项提供内容
    EditltemTemplate为当前编辑项提供内容
    HeaderTemplate为页眉提供内容
    FooterTemplate为页脚提供内容
    3.3.2. 分页显示DataList控件中的数据

    DataList本身不具有分页功能,为了实现分页功能,需要借助PagedDataSource类,例如这个例子

    在这里插入图片描述

    3.4. ListView控件

    3.4.1. ListView控件概述

    ListView控件用于显示数据,它提供了编辑、删除、插入、分页与排序等功能,ListView大部分的属性方法和事件与GridView和DataList一致,可以理解为GridView控件与DataList控件的融合,它具有GridView控件编辑数据的功能,同时又具有DataList控件灵活布局的功能。

    3.4.2. ListView控件的模板

    ListView控件有非常多的模板,其中最常用的有六个

    模板说明
    ItemTemplate为项提供内容
    GroupTemplate为组提供内容,它包含一个占位符对象,可以由其他模板中的内容进行替换
    SelectedltemTemplate为当前选定项提供内容
    EditltemTemplate为当前编辑项提供内容
    InsertltemTemplate为插入项提供内容
    EmptyDataTemplate在数据源未返回数据时提供内容
    3.4.3. 使用ListView控件对数据进行显示、分页和排序

    使用ListView控件对数据进行分页需要用到标签,这是一个用于分页的控件。排序需要用到CommandName属性,令其值为sort,指定要进行排序操作,然后再指定CommandArgument属性,令其值为要排序的列。

    使用ListView控件显示数据只需配置数据源即可,而无需写任何一行操作数据库的代码,效果如下:
    实现步骤
    在这里插入图片描述

    展开全文
  • 详情见博客:http://blog.csdn.net/qibin0506/article/details/47393725
  • Vue数据绑定以及双向绑定原理分析

    万次阅读 多人点赞 2018-05-08 23:35:36
    已经了解到vue是通过数据劫持的方式来做数据绑定的,其中最核心的方法便是通过Object.defineProperty()来实现对属性的劫持,达到监听数据变动的目的,无疑这个方法是本文中最重要、最基础的内容之一,如果不熟悉...

    效果

    这里写图片描述

    这里写图片描述

    这里写图片描述

    分析

    已经了解到vue是通过数据劫持的方式来做数据绑定的,其中最核心的方法便是通过Object.defineProperty()来实现对属性的劫持,达到监听数据变动的目的,无疑这个方法是本文中最重要、最基础的内容之一,如果不熟悉defineProperty,猛戳https://blog.csdn.net/c_kite/article/details/77950326
    整理了一下,要实现mvvm的双向绑定,就必须要实现以下几点:
    1、实现一个数据监听器Observer,能够对数据对象的所有属性进行监听,如有变动可拿到最新值并通知订阅者
    2、实现一个指令解析器Compile,对每个元素节点的指令进行扫描和解析,根据指令模板替换数据,以及绑定相应的更新函数
    3、实现一个Watcher,作为连接Observer和Compile的桥梁,能够订阅并收到每个属性变动的通知,执行指令绑定的相应回调函数,从而更新视图
    4、mvvm入口函数,整合以上三者

    这里写图片描述

    数据绑定

    MVVM

    // 创建一个Mvvm构造函数
    function Mvvm(options = {}) {   
        // vm.$options Vue上是将所有属性挂载到上面
        // 所以我们也同样实现,将所有属性挂载到了$options
        this.$options = options;
        // this._data 这里也和Vue一样
        let data = this._data = this.$options.data;
    
        // 数据劫持
        observe(data);
    }

    数据劫持

    数据劫持主要是采用es5的definePropeerty

    // 此处注意两个函数名单词的大小写
    
    // 创建一个Observe构造函数
    // 写数据劫持的主要逻辑
    function Observe(data) {
        // 所谓数据劫持就是给对象增加get,set
        // 先遍历一遍对象再说
        for (let key in data) {     // 把data属性通过defineProperty的方式定义属性
            let val = data[key];
            observe(val);   // 递归继续向下找,实现深度的数据劫持
            Object.defineProperty(data, key, {
                configurable: true,
                get() {
                    return val;
                },
                set(newVal) {   // 更改值的时候
                    if (val === newVal) {   // 设置的值和以前值一样就不理它
                        return;
                    }
                    val = newVal;   // 如果以后再获取值(get)的时候,将刚才设置的值再返回去
                    observe(newVal);    // 当设置为新值后,也需要把新值再去定义成属性
                }
            });
        }
    }
    
    // 外面再写一个函数
    // 不用每次调用都写个new
    // 也方便递归调用
    function observe(data) {
        // 如果不是对象的话就直接return掉
        // 防止递归溢出
        if (!data || typeof data !== 'object') return;
        return new Observe(data);
    }

    数据代理

    数据代理就是让我们每次拿data里的数据时,不用每次都写一长串,如mvvm._data.a.b这种,我们其实可以直接写成mvvm.a.b这种显而易见的方式

    下面我们在Mvvm这个函数里增加如下代码实现数据代理

    function Mvvm(options = {}) {
        // ...省略
        // 数据劫持
        observe(data);
        // this 代理了this._data
       for (let key in data) {
            Object.defineProperty(this, key, {
                configurable: true,
                get() {
                    return this._data[key];     // 如this.a = {b: 1}
                },
                set(newVal) {
                    this._data[key] = newVal;
                }
            });
       }
    }

    写到这里数据劫持和数据代理都实现了,那么接下来就需要编译一下了,把{{}}里面的内容解析出来

    数据编译

    这里写图片描述

    function Mvvm(options = {}) {
        // ...省略
    
        // 编译    
        new Compile(options.el, this);    
    }
    // 创建Compile构造函数
    function Compile(el, vm) {
        // 将el挂载到实例上方便调用
        vm.$el = document.querySelector(el);
        // 在el范围里将内容都拿到,当然不能一个一个的拿
        // 可以选择移到内存中去然后放入文档碎片中,节省开销
        let fragment = document.createDocumentFragment();
    
        while (child = vm.$el.firstChild) {
            fragment.appendChild(child);    // 此时将el中的内容放入内存中
             /* appendChild 成功后,会把节点从原来的节点位置移除;
                当进入 while 循环的下次执行(child = node.firstChild) 时, 这里面运算的 firstChild 已经变成了原先移除的下一个节点;
                直到 node 中再也没有节点时,(child = node.firstChild) 的返回值会为「false」, 这时循环就结束了,appendChild 也完成了。 */
        }
        // 对el里面的内容进行替换
        function replace(frag) {
            Array.from(frag.childNodes).forEach(node => {
                let txt = node.textContent;
                let reg = /\{\{\s*([^}]+\S)\s*\}\}/g;   // 正则匹配{{}}
    
                if (node.nodeType === 3 && reg.test(txt)) { // 即是文本节点又有大括号的情况{{}}
                    console.log(RegExp.$1); // 匹配到的第一个分组 如: a.b, c
                    let arr = RegExp.$1.split('.');
                    let val = vm;
                    arr.forEach(key => {
                        val = val[key];     // 如this.a.b
                    });
                    // 用trim方法去除一下首尾空格
                    node.textContent = txt.replace(reg, val).trim();
                }
                // 如果还有子节点,继续递归replace
                if (node.childNodes && node.childNodes.length) {
                    replace(node);
                }
            });
        }
    
        replace(fragment);  // 替换内容
    
        vm.$el.appendChild(fragment);   // 再将文档碎片放入el中
    }

    现在数据已经可以编译了,但是我们手动修改后的数据并没有在页面上发生改变

    下面我们就来看看怎么处理,其实这里就用到了特别常见的设计模式,发布订阅模式

    发布订阅

    发布订阅主要靠的就是数组关系,订阅就是放入函数,发布就是让数组里的函数执行

    // 发布订阅模式  订阅和发布 如[fn1, fn2, fn3]
    function Dep() {
        // 一个数组(存放函数的事件池)
        this.subs = [];
    }
    Dep.prototype = {
        addSub(sub) {   
            this.subs.push(sub);    
        },
        notify() {
            // 绑定的方法,都有一个update方法
            this.subs.forEach(sub => sub.update());
        }
    };
    
    
    
    // 监听函数
    // 通过Watcher这个类创建的实例,都拥有update方法
    function Watcher(fn) {
        this.fn = fn;   // 将fn放到实例上
    }
    Watcher.prototype.update = function() {
        this.fn();  
    };
    
    let watcher = new Watcher(() => console.log(111));  // 
    let dep = new Dep();
    dep.addSub(watcher);    // 将watcher放到数组中,watcher自带update方法, => [watcher]
    dep.addSub(watcher);
    dep.notify();   //  111, 111

    数据更新视图

    现在我们要订阅一个事件,当数据改变需要重新刷新视图,这就需要在replace替换的逻辑里来处理
    通过new Watcher把数据订阅一下,数据一变就执行改变内容的操作

    function replace(frag) {
        // 省略...
        node.textContent = txt.replace(reg, val).trim();
        // 监听变化
        // 给Watcher再添加两个参数,用来取新的值(newVal)给回调函数传参
       new Watcher(vm, RegExp.$1, newVal => {
            node.textContent = txt.replace(reg, newVal).trim();    
       });
    }
    
    // 重写Watcher构造函数
    function Watcher(vm, exp, fn) {
       this.fn = fn;
       this.vm = vm;
       this.exp = exp;
        // 添加一个事件
        // 这里我们先定义一个属性
       Dep.target = this;
       let arr = exp.split('.');
       let val = vm;
       arr.forEach(key => {    // 取值
          val = val[key];     // 获取到this.a.b,默认就会调用get方法
       });
       Dep.target = null; // 上面获取val[key]的时候会调用get方法, 因此使用完毕之后需要把该属性置位null
    }

    当获取值的时候就会自动调用get方法,于是我们去找一下数据劫持那里的get方法

    function Observe(data) {
       let dep = new Dep();
        // 省略...
        Object.defineProperty(data, key, {
            get() {
               Dep.target && dep.addSub(Dep.target);   // 将watcher添加到订阅事件中 [watcher]
                return val;
            },
            set(newVal) {
                if (val === newVal) {
                    return;
                }
                val = newVal;
                observe(newVal);
               dep.notify();   // 让所有watcher的update方法执行即可
            }
        })
    }

    当set修改值的时候执行了dep.notify方法,这个方法是执行watcherupdate方法,那么我们再对update进行修改一下

    Watcher.prototype.update = function() {
        // notify的时候值已经更改了
        // 再通过vm, exp来获取新的值
       let arr = this.exp.split('.');
       let val = this.vm;
       arr.forEach(key => {    
           val = val[key];   // 通过get获取到新的值
       });
        this.fn(val);   // 将每次拿到的新值去替换{{}}的内容即可
    };
    

    那么以上就是Vue的数据绑定的分析, 下面我们再来看看双向绑定


    双向绑定

        // html结构
        <input v-model="c" type="text">
    
        // 数据部分
        data: {
            a: {
                b: 1
            },
            c: 2
        }
    
        function replace(frag) {
            // 省略...
           if (node.nodeType === 1) {  // 元素节点
                let nodeAttr = node.attributes; // 获取dom上的所有属性,是个类数组
                Array.from(nodeAttr).forEach(attr => {
                    let name = attr.name;   // v-model  type
                    let exp = attr.value;   // c        text
                    if (name.includes('v-')){
                        node.value = vm[exp];   // this.c 为 2
                    }
                    // 监听变化
                    new Watcher(vm, exp, function(newVal) {
                        node.value = newVal;   // 当watcher触发时会自动将内容放进输入框中
                    });
    
                    node.addEventListener('input', e => {
                        let newVal = e.target.value;
                        // 相当于给this.c赋了一个新值
                        // 而值的改变会调用set,set中又会调用notify,notify中调用watcher的update方法实现了更新
                        vm[exp] = newVal;   
                    });
                });
           }
            if (node.childNodes && node.childNodes.length) {
                replace(node);
            }
        }
    

    computed(计算属性) && mounted(钩子函数)

        // html结构
        <p>求和的值是{{sum}}</p>
    
        data: { a: 1, b: 9 },
        computed: {
            sum() {
                return this.a + this.b;
            },
            noop() {}
        },
        mounted() {
            setTimeout(() => {
                console.log('所有事情都搞定了');
            }, 1000);
        }
    
        function Mvvm(options = {}) {
            // 初始化computed,将this指向实例
           initComputed.call(this);     
            // 编译
            new Compile(options.el, this);
            // 所有事情处理好后执行mounted钩子函数
           options.mounted.call(this); // 这就实现了mounted钩子函数
        }
    
        function initComputed() {
            let vm = this;
            let computed = this.$options.computed;  // 从options上拿到computed属性   {sum: ƒ, noop: ƒ}
            // 得到的都是对象的key可以通过Object.keys转化为数组
            Object.keys(computed).forEach(key => {  // key就是sum,noop
                Object.defineProperty(vm, key, {
                    // 这里判断是computed里的key是对象还是函数
                    // 如果是函数直接就会调get方法
                    // 如果是对象的话,手动调一下get方法即可
                    // 如: sum() {return this.a + this.b;},他们获取a和b的值就会调用get方法
                    // 所以不需要new Watcher去监听变化了
                    get: typeof computed[key] === 'function' ? computed[key] : computed[key].get,
                    set() {}
                });
            });
        }
    

    总结

    下面是完整代码实现
    https://github.com/TheKiteRunners/Vue-2KindsOfBinding

    参考链接:

    https://segmentfault.com/a/1190000006599500
    https://juejin.im/post/5abdd6f6f265da23793c4458

    展开全文
  • WPF下DataGrid每行设置不同的ComboBox的数据绑定 DataGrid设置一次ItemSource 每个ComboBox也要设置一次ItemSource 有点像通过两次映射来绑定
  • WPF TabControl 数据绑定

    千次阅读 2020-05-22 20:03:17
    简单版数据绑定使用 定义数据模型与数据绑定 MainWindow.xaml.cs /* * function: TabControl in DataBinding's world * description: Using TabControl to Binding * author: Mei Liyong */ using System....
  • Vue(三)——数据绑定

    千次阅读 2019-04-30 23:41:00
    数据绑定 简单文本绑定 最简单也是最常用的数据绑定方法,通过使用{{}}标签来绑定数据: var app = new Vue({ el : '#app', data : { name: 'hengyumo' } }) <span>Hello, this is {{name}}</span>...
  • 理解VUE双向数据绑定原理和实现

    万次阅读 多人点赞 2021-02-26 12:04:02
    1.vue 双向数据绑定是通过 数据劫持 结合 发布订阅模式的方式来实现的, 也就是说数据和视图同步,数据发生变化,视图跟着变化,视图变化,数据也随之发生改变; 2.核心:关于VUE双向数据绑定,其核心是 Object....
  • SpringMVC数据绑定

    千次阅读 2021-06-13 21:15:30
    参考应用ch4创建应用practice44。在应用practice44中创建两个视图页面addGoods.jsp和goodsList.jsp。addGoods.jsp页面的显示效果如图4.5所示,goodsList.jsp页面的显示效果如图4.6所示。 图4.5 添加商品页面 ...
  • 双向数据绑定原理

    千次阅读 2020-10-27 16:47:48
    1.双向数据绑定是通过数据劫持结合发布订阅者的模式和object.defineproprety()来劫持各个属性的setter、getter,如果数据有变动,就发布消息给订阅者触发监听。 2.双向数据绑定的步骤: **第一步:**实现一个数据...
  • 本示例介绍了自定义服务器控件的开发,以及其绑定数据的方法,供参考使用。
  • WPF mvvm数据绑定

    热门讨论 2013-09-25 08:44:45
    WPF mvvm数据绑定 http://blog.csdn.net/wuwo333/article/details/11973499
  • v-model双向数据绑定

    千次阅读 2022-03-30 15:16:28
    双向数据绑定 主要用于给表单元素创建双向数据绑定。 即: 1.视图发生改变→数据发生对应的改变。即用户在视图(网页)上通过输入等操作,改变原数据。 2.数据改变→视图发生对应的改变。即在js中的数据本身发生改变...
  • 微信小程序04 数据绑定

    千次阅读 2022-03-07 10:54:18
    一、数据绑定的基本原则 1、在data中定义数据 即在页面对应的.js文件中,把数据定义到data对象中即可 2、在 wxml 中使用数据 把data中的数据绑定到页面中渲染,使用Mustache(相当于插值表达式)将变量包起来即可,...
  • Spring MVC数据绑定(简单数据绑定)

    千次阅读 2018-04-12 14:38:34
    首先,什么是数据绑定呢? 在执行程序时,Spring MVC会根据客户端请求参数的不同,将请求消息中的信息以一定的方式转换并绑定到控制器类的方法参数中。这种将请求消息数据与后台方法参数建立连接的过程就是Spring MVC...
  • 全面介绍Android的MVVM框架 - 数据绑定

    万次阅读 多人点赞 2019-12-05 17:00:09
    至此,一个简单的数据绑定就完成了,可参考 完整代码 高级用法 使用类方法 首先为类添加一个静态方法 public class MyStringUtils { public static String capitalize ( final String word ) ...
  • table表格数据绑定

    千次阅读 2019-04-18 08:59:45
    table表格数据绑定 开发工具与关键技术:VS、table表格数据绑定 作者:黄桂康 撰写时间:2019.04.16 上一次我们也讲了关于表格数据绑定的有关文章,但本篇是全表格数据绑定的介绍,table表格是我们经常用到的一种...
  • vue中的双向数据绑定详解

    千次阅读 2020-12-23 06:52:06
    前言什么是数据双向绑定?vue是一个mvvm框架,即数据双向绑定,即当数据发生变化的时候,视图也就发生变化,当视图发生变化的时候,数据也会跟着...如果我们使用vuex,那么数据流也是单项的,这时就会和双向数据绑定...
  • 详解单向数据流与双向数据绑定

    千次阅读 多人点赞 2019-06-06 17:54:58
    在学习和接触 Vue 的过程中,接触到 Vue 的两个特性,单向数据流与双向数据绑定,他们是什么,特点如何,以及彼此之间的关系和联系又有什么,接下来,我们深入的探究一下它们。 单向数据流 数据流,表明的是数据...
  • thymeleaf前端数据绑定

    千次阅读 2019-02-15 09:50:44
    thymeleaf是一种模板,如果想在html对表格进行绑定,可以这么做: &amp;lt;html xmlns:th=&quot;http://www.thymeleaf.org&quot;&amp;gt; &amp;lt;script th:src=&quot;@{../pages/js/art-...
  • Android DataBinding 双向数据绑定、事件绑定、使用类方法 一、Android DataBinding 基础使用 二、Android DataBinding单向绑定 双向数据绑定 双向绑定的意思即为当数据改变时同时使视图刷新,而视图改变时也可以...
  • Vue 双向数据绑定原理

    千次阅读 2020-09-16 23:13:40
    1、vue双向数据绑定原理,又称vue响应式原理,是vue的核心,双向数据绑定是通过数据劫持结合发布者订阅者模式的方式来实现的,通过Object.defineProperty()来劫持各个属性的 setter,getter,在数据变动时发布消息给...
  • Vue双向数据绑定原理(面试必问)

    千次阅读 2021-01-08 14:26:31
    vue.js是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调来渲染视图。 具体步骤 需要observer的数据...
  • Windows Forms 2.0数据绑定(第一部分)

    热门讨论 2011-11-02 23:43:52
    本书是Windows Forms 2.0数据绑定技术的最佳使用指南。  全书共包括10章和4个附录,对数据绑定技术进行了全面而深入的讲解。前半部分讨论了如何使用Windows Forms 2.0和Visual Studio 2005提供的强大的数据绑定特性...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,286,643
精华内容 514,657
关键字:

数据绑定