【问题标题】:Updating Knockout observables through jQuery event handlers通过 jQuery 事件处理程序更新 Knockout observables
【发布时间】:2016-12-13 17:32:25
【问题描述】:

我知道将 jQuery 事件处理程序与 Knockout 一起使用是不好的做法,但目前我想继续我开始的这条道路。正如我在this Fiddle 中所阐述的那样,我正在寻找关于如何使用 jQuery 中的 click 事件来使用 observables 更新视图模型的说明。

预期的行为是:单击颜色按钮(即Red, Green, Blue),然后单击UPDATE! 以显示相应颜色的数据。例如,点击红色 -> 更新会在 DOM 中吐出“红花太阳”。然后点击蓝色->更新会产生“蓝天海洋”。

我认为问题出在我的 observables 和 with: colors 数据绑定上,但我不完全明白为什么。对我来说,这基本上是为期 2 天的 Knockout 速成课程,我觉得其中的很多内容应该比以前容易得多。

请给我看灯!

HTML

<div data-bind="with: colors">
  <h4 data-bind="text: name"></h4>
  <div data-bind="foreach: things">
    <span data-bind="text: $data" />
  </div>
</div>

JavaScript

function Sample(data) {
  var self = this;

  self.colors = ko.observableArray();
  self.currentColor = ko.observable();

  ko.mapping.fromJS(data, {}, self);
}

var sample = new Sample({
  "colors": [{
    "name": "red",
    "things": ["flower", "sun"]
  }, {
    "name": "green",
    "things": ["tree", "money"]
  }, {
    "name": "blue",
    "things": ["sky", "ocean"]
  }]
});

ko.applyBindings(sample);

var clicked;
$("button").on("click", function() {
  clicked = this.className;
});

$(".update").on("click", function() {
  if (clicked === "red") {
    // ???    
  }
  if (clicked === "green") {
    // ???    
  }
  if (clicked === "blue") {
    // ???    
  }
});

【问题讨论】:

    标签: javascript jquery arrays json knockout.js


    【解决方案1】:

    我更新了你的小提琴以匹配你想要的。 但我希望你真的无视这种方式。 检查这个fiddle

    我在那里做的是找到具有nameclicked 变量的颜色。

    $(".update").on("click", function() {
      var foundColor = sample.colors().find(function(color){
        return color.name() === clicked;
      });
      sample.currentColor(foundColor);
    });
    

    你的 with 绑定的值应该是 currentColor 而不是你的 observable 数组。

    <div data-bind="with: currentColor">
    

    但是,这仍然不是正确的方法,您应该阅读click 绑定,它将帮助您入门,并且将对此进行更清晰的实现,并且更短。

    【讨论】:

      【解决方案2】:

      如果要渲染所有颜色,则必须使用 foreach 绑定。这有点像 with 自动绑定 colors 数组中的每个项目:

      <div data-bind="foreach: colors"> ... </div>
      

      我认为当你使用敲除时你不应该使用 jQuery 来处理,所以我将解释如何使用click 绑定。

      点击绑定的基本布局是:

      click: function(currentlyBoundData, event) { /* ... */ }
      

      这意味着,当您将它与foreach 绑定一起使用时,它会连同点击事件一起发送点击数据。

      让我们首先为您的视图模型添加一个点击处理程序:

      self.clickHandler = function(clickedItem, event) {
        console.log(clickedItem);
      };
      

      现在,将此处理程序方法附加到对每种颜色的点击:

      <div data-bind="foreach: colors">
        <h4 data-bind="text: name, click: $parent.clickHandler"></h4>
      </div>
      

      注意$parent:它链接到foreach 级别的数据绑定上下文,即Sample 视图模型。

      现在您已经创建了一个可以被所有颜色重用的方法,您可以编写剩余的逻辑:

      1. 知道您通过向其传递参数来设置可观察对象,
      2. 并且知道 click 绑定将单击的项目作为第一个参数传递

      我们可以直接将 observable 绑定到 click 方法

      1. 像这样:data-bind="click: $parent.currentColor"

      最后,您需要一个update 方法:

      1. 通过不带参数调用它来获取currentColorself.currentColor()
      2. 并将其放入一个新的 observable 中,命名为 selectedColor: self.selectedColor(self.currentColor())

      function Sample(data) {
        var self = this;
      
        self.colors = ko.observableArray();
        self.currentColor = ko.observable();
        self.selectedColor = ko.observable();
      
        self.updateColor = function() {
          self.selectedColor(self.currentColor());
        };
      
        ko.mapping.fromJS(data, {}, self);
      }
      
      var sample = new Sample({
        "colors": [{
          "name": "red",
          "things": ["flower", "sun"]
        }, {
          "name": "green",
          "things": ["tree", "money"]
        }, {
          "name": "blue",
          "things": ["sky", "ocean"]
        }]
      });
      
      ko.applyBindings(sample);
      .selected {
        background: yellow;
      }
      <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.min.js"></script>
      
      <div data-bind="foreach: colors">
        <h4 data-bind="text: name, click: $parent.currentColor, css: {'selected' : $parent.currentColor() === $data}"></h4>
      </div>
      
      <button data-bind="click: updateColor">load last clicked</button>
      
      <div data-bind="with: selectedColor">
        Selection: <strong data-bind="text: name"></strong>
      </div>

      【讨论】:

      • 虽然这与我的特定用例不匹配,但这是一个非常详细和有启发性的答案。谢谢。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多