rivets.js试图让自定义适配器工作

时间:2016-06-18 19:14:03

标签: javascript model-binding rivets.js

我正在尝试使用自定义适配器来处理rivets.js,但它既不会更改模型也不会调用例程。如果有人也在使用rivets.js,我可以使用这个帮助:

JsFiddle Example Code



var menuContext = {
  menu: {
    watchList: {
      status: false,
      view: function() {
        // call other view
      }
    },
    profile: {
      status: false,
      view: function() {
        // call other view
      }
    }
  }
};

rivets.binders['on-select-item'] = {

  bind: function(el) {

    var adapter = rivets.adapters[rivets.rootInterface];
    var model = this.model;
    var keypath = this.keypath;
    var that = this;
    this.callback = function(ev) {
      ev.preventDefault();
      var value = adapter.get(model, keypath);

      var newValue = !value;

      adapter.set(model, keypath, newValue);

    };
    el.addEventListener('click', this.callback);
  },
  unbind: function(el, value) {
    el.removeEventListener('click', this.callback);
  },
  routine: function(el, value) {

    console.log('I am only being called once!');
  
    value ? el.classList.add('enabled') : el.classList.remove('enabled');
  }
};

var menu = document.querySelector("#menu");


rivets.bind(menu, menuContext);

#menu .enabled {
  background-color: green;
}

<script src="https://rawgit.com/mikeric/rivets/master/dist/rivets.bundled.min.js"></script>
<ul id="menu">
  <li>
    <a href="#" role="button" rv-on-select-item="menu.watchList.status">
    Item 1, value should toggle (true|false) <span rv-html="menu.watchList.status"></span>
		  		</a>
  </li>
  <li>
    <a href="#" role="button" rv-on-select-item="menu.profile.status">
		    		Item 2, value value should toggle (true|false) <span rv-html="menu.profile.status"></span>
		  		</a>
  </li>
</ul>
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:0)

此处的keypath是您在模板中指定的完整路径字符串,但此处的模型是保存keypath中最后一个属性的对象(不要问我为什么,这是如何调试并查看source code of default adapter,它似乎没有进行任何遍历:

get: function(obj, keypath) {
  return obj[keypath];
},
set: function(obj, keypath, value) {
  return obj[keypath] = value;
}

所以你必须自己解决keypath。在这种情况下,会发生以下情况:

var menuContext = {
  menu: {
    watchList: {
      status: false,
      view: function() {
        // call other view
      }
    },
    profile: {
      status: false,
      view: function() {
        // call other view
      }
    }
  }
};

rivets.binders['on-select-item'] = {

  bind: function(el) {
    var adapter = rivets.adapters[rivets.rootInterface];
    var model = this.model;
    var keypath = this.keypath;
    var that = this;
    this.callback = function(ev) {
      ev.preventDefault();
      var key = keypath.split('.').slice(-1);
      var value = adapter.get(model, key);
      var newValue = !value;
      adapter.set(model, key, newValue);
    };
    el.addEventListener('click', this.callback);
  },
  unbind: function(el, value) {
    el.removeEventListener('click', this.callback);
  },
  routine: function(el, value) {

    console.log('I am only being called once!');

    value ? el.classList.add('enabled') : el.classList.remove('enabled');
  }
};

var menu = document.querySelector("#menu");


rivets.bind(menu, menuContext);
#menu .enabled {
  background-color: green;
}
<script src="https://rawgit.com/mikeric/rivets/master/dist/rivets.bundled.min.js"></script>
<ul id="menu">
  <li>
    <a href="#" role="button" rv-on-select-item="menu.watchList.status">
    Item 1, value should toggle (true|false) <span rv-html="menu.watchList.status"></span>
		  		</a>
  </li>
  <li>
    <a href="#" role="button" rv-on-select-item="menu.profile.status">
		    		Item 2, value value should toggle (true|false) <span rv-html="menu.profile.status"></span>
		  		</a>
  </li>
</ul>

我知道你在官方网站上遵循双向绑定example,但是图书馆似乎已经有了重大更新。如果你想知道“为什么”更好的地方是github repo作者可以提供一些见解。