mvc-4控制器和状态(2)

访问视图

常见地视图模式时一个视图对应一个控制器,视图包含一个id,通过id传入控制器;在视图之中的元素则使用class

这里会使用jquery的选择器,为了减少使用,可以设置一个专门用于存放选择器到变量的映射表

<div id="users">
  <form>
    <input type="search" value="" placeholder="Enter a query">
    <button type="button">Search</button>
  </form>
</div>

jQuery(function($) {
  exports.SearchView = Controller.create({
    //选择器局部变量名地映射
    elements: {
      "input[type=search]": "searchInput",
      "form": "searchForm"
    },
    //实例化时调用
    init: function(elem) {
      this.el = $(elem);
      this.refreshElements();
      this.searchForm.submit(this.proxy(this.search));
    },
    search: function() {
      console.log("Searching:", this.searchInput.val());
    },
    //私有
    $: function(selector) {
      //需要一个el属性,同时传入选择器
      return $(selector, this.el);
    },
    //设置本地变量
    refreshElements: function() {
      for(var key in this.elements) {
        this[this.elements[key]] = this.$(key);
      }
    }
  });
  new SearchView("#users");
});

委托事件

通过设置一个events对象代理,进行事件的委托和移除

jQuery(function($){
  exports.SearchView = Controller.create({
  //所有事件名称,选择器和回调的映射
    events: {
      "submit form": "search"
    },
    init: function(element){
      //.....
      this.delegateEvents();
    },
    search: function(){
      //...
    },
      //根据第一个空格分割
    eventSplitter: /^(w+)s*(.*)$/,
    
    delegateEvents: function(){
      for (var key in this.events) {
        var methodName = this.events[key];
        var method     = this.proxy(this[methodName]);
        var match      = key.match(this.eventSplitter);
        var eventName  = match[1], selector = match[2];
        if (selector === '') {
          this.el.bind(eventName, method);
        } else {
          this.el.delegate(selector, eventName, method);
        }
      }
    }  
  });
  new SearchView("#users");
});

状态机

  • 作用:管理多控制器,根据需要显示和隐藏视图

  • 组成: 状态和转换器; 它包含一个活动状态和许多非活动状态;

  var Events = {
    bind: function() {
      this.o = this.o || $({});
      this.o.bind.apply(this.o ,arguments);
    },
    trigger: function() {
      this.o = this.o || $({});
      this.o.trigger.apply(this.o, arguments);
    }
  }

  var StateManchine = function() {};
  StateManchine.fn =StateManchine.prototype;
  //添加事件绑定或触发行为
  $.extend(StateManchine.fn, Events);
  //这个add函数将传入的控制器添加至状态列表并创建一个active函数;当调用active的时候,控制器状态转化为激活状态,对于激活状态的控制器,状态将基于它调用activate,对于其他控制器,状态机会调用deactivate;
  StateManchine.fn.add = function(controller) {
    this.bind("change", function(e, current) {
      if(controller == current)
        controller.activate();
      else
        controller.deactivate();
    });
    controller.active = $.proxy(function() {
      this.trigger("change", controller);
    }, this);
  };

 //使用
 var con1 = {
  activate: function() {
    $("#con1").addClass("active");
  },
  deactivate: function() {
    $("#con1").removeClass("active");
  }
 };
 var con2 = {
  activate: function() {
    $("#con2").addClass("active");
  },
  deactivate: function() {
    $("#con2").removeClass("active");
  }
 };
 //创建状态机并添加状态
 var sm = new StateManchine;
 sm.add(con1);
 sm.add(con2);
 
 //会触发con1.activate;con2.deactivate;
 con1.active();

 //会触发con2.activate;con1.deactivate;
 sm.trigger("change", con2);

路由选择

由于应用是单页面的,URL一般不会变;当考虑到具体情况,需要对其进行改变

使用URL中的hash####

改变URL会造成页面刷新;操作URL的一种办法是改变hash值,因为hash不会发送给服务器,改变其不会造成刷新

//设置
 window.location.hash = "foo";
//去掉#
var hashValue = window.location.hash.slice(1);

注意要限制这种改动的次数,过多的设置hash会影响性能,特别是在移动端,可能会造成页面频繁滚动

检测hash的变化####

监听

window.addEventListener('hashchange', function(event){});
  • 设置location.hash或修改hash后重新载入时触发;
原文地址:https://www.cnblogs.com/jinkspeng/p/4230556.html