mvc-5视图和模版

动态渲染视图

  • 当待渲染的视图内容不多的时候,可以将视图元素放在控制器或者状态里
var views = document.getElementById("views");
views.innerHTML = ""; //将元素内容清空

var container = document.createElement("div");
container.id = "user"; //设置id

var name = document.createElement("span");
name.innerHTML = data.name;

container.appendChild(name);
views.appendChild(container);

//或使用jquery

$("#views").empty();
var container = $("<div/>").attr({id: "user"});
var name = $("<span/>").text(data.name);
$("#views").append(container.append(name));
  • 此外也可以将静态页面包含再页面中,再必要时候显示或隐藏;

模版

js模版的核心概念是,将包含模版变量的HTML片段和JavaScript对象做合并,把模版变量替换为对象中的属性值, 以下都以jquery.tmpl模版为例

<script type="text/javascript">
  var object = {
  	url: "https://www.google.com/",
  	getName: function () {
  		return "testName";
  	}
  };
  var tmpl = '<li><a href="${url}">${getName()}</a></li>';
  var elem = jQuery.tmpl(tmpl, object);
  $("body").append(elem);
</script>
//
<script id="tmpl" type="text/template">
	<li><a href="${url}">${getName()}</a></li>
</script>
<script type="text/javascript">
  var object = {
  	url: "https://www.google.com/",
  	getName: function () {
  		return "testName";
  	}
  };
  var elem = $("#tmpl").tmpl(object);
  elem.appendTo($("body"));
</script>
  • 一些高级功能
<script type="text/template" id="tmpl">
	{{if url}}
	  ${url}
	{{/if}} 

	{{if messages.length}}
	  <ul>
	    {{each messages}}
	    <li>${$index + 1}: <em>${$value}</em></li>
	    {{/each}}
	{{else}}
	  no messages
	{{/if}}
</script>
<script type="text/javascript">
  var object = {
  	url: "https://www.google.com/",
  	messages: ['one', 'two'] 
  };
  var elem = $("#tmpl").tmpl(object);
  $("body").append(elem);
</script>

可以用$value变量来访问当前正被遍历的值;数组元素的索引可以使用$index变量来输出

模版helper

有时再视图内部使用通用helper函数,比如格式化一个日期或数字;为了保持mvc架构,最好的方法应该是将它们抽象出来,并用命名空间进行管理,而不是直接将函数掺进视图中,这样才能保持逻辑和视图之间的解偶

//替换一段纯文本中的<a></a>标签里的链接

<script type="text/tamplate" id="tmpl">
  ${helper.autoLink(this.data)}	 //这里data指代tmpl()方法传入的数据;
</script>
<script type="text/javascript">
  var helper = {};
  helper.autoLink = function(data) {
    var re = /((http|https|ftp):\/\/[\w?=&.\/-;#~%-]+(?![\w\s?&.\/;#~%"=-]*>]))/g;
    console.log(data);
    return (data.replace(re, '<a target="_blank" href="$1">$1</a>'));	
  };
  var elem = $("#tmpl").tmpl("https://github.com/maccman/jquery.tmpl");
  $("body").append(elem);
</script>

模版存储

包括

  • JavaScript中以行内形式存储;//违背了MVC架构原则,不推荐
  • 在自定义script标签里以行内形式存储; //推荐,通过Id来获取模版引用;浏览器不会对它们进行渲染而仅解析为内容文本
  • 远处加载; //注意速度问题
  • 在HTML中以行内形式存储
<script type="text/tamplate" id="tmpl">
  <span>${getName()}</span>
</script>
<script type="text/javascript">
 var data = {
 	getName: function() {return "Bob"}
 };
 var element = $("#tmpl").tmpl(data);
 element.appendTo($("body"));
</script>
  • 在程序后台,jquery.tmpl会确保模版一旦生成后,解析后的模版就能被缓存住,而不必2次解析;
  • 首先根据内容生成元素,然后将它追加到页面中,这种方式性能比操作已经追加至页面的元素更好,这是一种最佳实践
  • 实际上运用一些“依赖管理工具”会更加简洁,如RequireJS

绑定

绑定将视图元素和js对象(通常是模型)挂接在一起;当js对象发生改变时,视图会根据新修改后的对象做适时更新

为了将js对象和视图绑定在一起,需要设置一个回调函数,当对象的熟悉发生改变时发送一个更新视图的通知

  var addChange = function (ob) {
    ob.change = function(cb) {
      if(cb) {
        if(!this._change) this._change = [];
        this._change.push(cb);
      } else {
        if(!this._change) return;
        for(var i = 0, len = this._change.length; i < len; i++) {
            this._change[i].apply(this);
        }
      }
    }
  } 

  var object = {};
  object.name = 'Foo';

  addChange(object);
  object.change(function() {
    console.log("Changed!", this);
    //添加更新视图的代码
  });

  object.change();
  object.name = "Bar";
  object.change();

给这个对象添加了change()回调, 这样就可以执行绑定和触发change事件

模型中的事件绑定

<script type="text/javascript" charset="utf-8">
    var User = function(name){
      this.name = name;
    };
    User.records = []
    User.bind = function(ev, callback) {
      var calls = this._callbacks || (this._callbacks = {});
      (this._callbacks[ev] || (this._callbacks[ev] = [])).push(callback);
    };
    User.trigger = function(ev) {
      var list, calls, i, l;
      if (!(calls = this._callbacks)) return this;
      if (!(list  = this._callbacks[ev])) return this;
      jQuery.each(list, function(){ this() })
    };
    
    User.create = function(name){
      this.records.push(new this(name));
      this.trigger("change")
    };
    jQuery(function($){
      User.bind("change", function(){
        var template = $("#userTmpl").tmpl(User.records);
    
        $("#users").empty();        
        $("#users").append(template);
      });
      
      User.create("First one");
      
      setTimeout(function(){
        User.create("Another one");
      }, 2000);
    });
  </script>
</head>

<body>
  <script id="userTmpl" type="text/x-jquery-tmpl">
    <li>${name}</li>
  </script>
  
  <ul id="users">
  </ul>
</body>
posted @ 2015-01-17 16:23  JinksPeng  阅读(251)  评论(0编辑  收藏  举报