同一视图中的多个挖空组件

sun*_*tal 7 javascript knockout.js

我已经高低搜索了这个答案,但是对于我的生活来说,除了我认为我的用例有点复杂之外我不知道我在做什么与官方例子有什么不同之处:

http://knockoutjs.com/documentation/component-binding.html

基本上,我正在尝试创建可重用的UI元素.行为将基本上通过"params"对象传递给它们.我希望多个元素能够存在于单个页面上,然而,这是我遇到困难的地方.

我正在使用browserify捆绑我的代码并具有以下内容(为简洁起见,某些条目被截断):

的index.html

<div data-bind='component: { name: "toggle" , params: {
   enabledText: "Parental controls are enabled",
   disabledText: "Parental controls are disabled"
 }}'></div>
 <div data-bind='component: { name: "toggle" , params: {
   enabledText: "Same component, different behavior: enabled",
   disabledText: "Same component, different behavior: disabled"
 }}'></div>
Run Code Online (Sandbox Code Playgroud)

main.js

var ko = window.ko = require('knockout'),
    toggle = require('./components/toggle/toggle');

ko.components.register('toggle', toggle);

function Container() {

}

var con = new Container();

ko.applyBindings(con);
Run Code Online (Sandbox Code Playgroud)

组件/拨动/ toggle.js

var ko = require('knockout'),
    template = require('./toggle.html');

function vm(params) {
  var self = this;
  self.enabled = ko.observable(false);
  self.label = ko.computed(function() {
    return self.enabled() ? params.enabledText : params.disabledText;
  });
}

module.exports = { viewModel: vm, template: template };
Run Code Online (Sandbox Code Playgroud)

最后,在components/toggle/toggle.html中:

<input type='checkbox' data-bind='checked: enabled' id='switch-checkbox' class='switch-input' />
<label for='switch-checkbox' class='switch-input-label'>
  <span data-bind='text: label'></span>
</label>
Run Code Online (Sandbox Code Playgroud)

我遇到的问题是组件都适当地出现在页面上,但是点击第二个组件会激活第一个组件(并且对seconD没有任何作用).我是Knockout的新手并且显然遗漏了一些东西,但我无法弄清楚如何解决我的问题.任何帮助将非常感谢!

奇怪的是标签是相应的唯一,表明为每个HTML实体实例化的组件(视图模型)实际上是唯一的...但是,似乎敲门的"已检查"绑定仅绑定到第一个.

编辑:我知道包含一个例子的惯例,所以这里有一个在codepen上.我为使用浏览器代码道歉,但希望它仍然可读:

http://codepen.io/sunny-mittal/pen/OVBNwp

Ani*_*tel 7

当加载该组件的多个实例id的属性input标签和for该属性label的标签,使你的内容,它也不再会是唯一的页面.

您基本上有两个input标记相同id,两个label标记定位一个标记id.你label for="switch-checkbox"的第二个组件是input id="switch-component"从第一个组件而不是第二个组件.

虽然淘汰组件很棒,但遗憾的是组件实例之间没有隔离.

要解决此问题,您需要确保组件的每个实例的值idfor整个页面的唯一值.

我已经在这个工作中包含了一个片段.

var uid = function(){
  var seed = 1;
  return { 
    new: function(p){
      return p + (seed++);
    }
  }
}();


    var template =
      "<input type='checkbox' data-bind='checked: enabled, attr: {id:id}' class='switch-input' />\n<label data-bind='attr: {for: id}' class='switch-input-label'>\n  <span data-bind='text: label'></span>\n</label>\n";

    var viewModel = function vm(params) {
      var self = this;
      self.id = uid.new('switch-checkbox-');
      self.enabled = ko.observable(false);
      self.label = ko.computed(function() {
        return self.enabled() ? params.enabledText : params.disabledText;
      });
    }

    var component = {
      viewModel: viewModel,
      template: template
    };

    ko.components.register('toggle', component);

    var vm = {};

    ko.applyBindings(vm);
Run Code Online (Sandbox Code Playgroud)
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
html {
  position: relative;
  height: 100%;
  min-height: 100%;
}
.switch-input {
  display: none;
}
.switch-input-label {
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  -o-user-select: none;
  user-select: none;
  position: relative;
  display: inline-block;
  cursor: pointer;
  font-weight: 500;
  text-align: left;
  margin: 16px;
  padding: 16px 0 16px 44px;
}
.switch-input-label:before,
.switch-input-label:after {
  content: '';
  position: absolute;
  margin: 0;
  outline: 0;
  top: 50%;
  transform: translate(0, -50%);
  transition: all 0.3s ease;
}
.switch-input-label:before {
  left: 1px;
  width: 34px;
  height: 14px;
  background-color: #9e9e9e;
  border-radius: 8px;
}
.switch-input-label:after {
  left: 0;
  width: 20px;
  height: 20px;
  background-color: #fafafa;
  border-radius: 50%;
  box-shadow: 0 3px 1px -2px rgba(0, 0, 0, 0.14), 0 2px 2px 0 rgba(0, 0, 0, 0.098), 0 1px 5px 0 rgba(0, 0, 0, 0.084);
}
.switch-input:checked + .switch-input-label:before {
  background-color: #a5d6a7;
}
.switch-input:checked + .switch-input-label:after {
  background-color: #4caf50;
  transform: translate(80%, -50%);
}
Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>


<div data-bind='component: { name: "toggle" , params: {
   enabledText: "Parental controls are enabled",
   disabledText: "Parental controls are disabled"
 }}'></div>

<div data-bind='component: { name: "toggle" , params: {
   enabledText: "Same component, different behavior: enabled",
   disabledText: "Same component, different behavior: disabled"
 }}'></div>

<div data-bind='component: { name: "toggle" , params: {
   enabledText: "Same component, another instance: enabled",
   disabledText: "Same component, another instance: disabled"
 }}'></div>
Run Code Online (Sandbox Code Playgroud)