事件功能不起作用

时间:2016-01-11 04:03:28

标签: knockout.js

我有一个绑定事件功能的按钮:

<button type="button" data-bind="event: { click: deleteWrapper},
   attr: {'data-wrapper': wrapper_id}">Delete</button>

在js文件中(使用jQuery和Knockout编写)我有一个这样的可观察变量:

isChecked: ko.observable(false)

deleteWrapper函数:

deleteWrapper: function(data, event) {
    var self = this;
    var clickedId = event.target.getAttribute('data-wrapper');
},

当我提醒clickedId或任意字符串时,它没关系,但是当我想提醒isChecked的值时:

alert(self.isChecked());

它没有显示任何内容。我尝试过使用其他observableobservableArray,但也没有用。但是,当我尝试与其他功能完全相同的东西,它工作。事件功能有问题吗?

3 个答案:

答案 0 :(得分:1)

在ko中,您可以将click事件直接附加到click binding的函数,如下所示:

<button type="button" data-bind="click: deleteWrapper

我认为这是一个拼写错误,但您必须指定函数名称,而不必在其前面添加$(如上所示)。

处理ko事件的函数,在本例中为deleteWrapperreceives the model value in the context of the bound element as first parameter。所以你的功能应该是这样的:

deleteWrapper: function(data) {
    /* data is the data bound to the button */
    var clickedId = data.wrapper_id;
},

我不知道你想对deleteWrapper函数做什么,但你可以直接从接收到的参数访问绑定数据,如上所示。

我都不知道您在尝试运行此代码的位置:alert(self.isChecked());但是,如果self实际上是isChecked()所属的对象,那么这应该可行。

答案 1 :(得分:1)

糟糕!不要像那样混合Knockout和jQuery。 Knockout是一个MVVM库,您不应该需要jQuery和data-属性。

以下是如何在Knockout中执行此操作:

&#13;
&#13;
var item1 = { name: "Item ONE", isChecked: ko.observable(false) };
var item2 = { name: "Item TWO", isChecked: ko.observable(true) };
var item3 = { name: "Item THREE", isChecked: ko.observable(false) };

var rootViewModel = {
  items: ko.observableArray([item1, item2, item3])
};

rootViewModel.deleteWrapper = function(item) {
  alert(item.isChecked());
  rootViewModel.items.remove(item);
};

ko.applyBindings(rootViewModel);
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

<ul data-bind="foreach: items">
  <li>
    <span data-bind="text: name"></span>
    <input type="checkbox" data-bind="checked: isChecked">
    <button type="button" data-bind="click: $root.deleteWrapper">Delete</button>
  </li>
</ul>
&#13;
&#13;
&#13;

这个解决方案的要点:

  • 具有处理视图模型上的删除的功能;
  • 该函数将上下文$data(即项目)作为参数;
  • 在视图模型中有所有逻辑(您可以对其进行单元测试);
  • 保持观点&#34; dumb&#34;,仅反映视图模型的最新状态;

我还建议使用构造函数或类似的模式来简化视图模型的工作方式。

PS。作为脚注,如果您坚持遵循您选择的路线,请按照以下步骤操作:

&#13;
&#13;
var item1 = { wrapper_id: 1, name: "Item ONE", isChecked: ko.observable(false) };
var item2 = { wrapper_id: 2, name: "Item TWO", isChecked: ko.observable(true) };
var item3 = { wrapper_id: 3, name: "Item THREE", isChecked: ko.observable(false) };

var rootViewModel = {
  items: ko.observableArray([item1, item2, item3])
};

rootViewModel.deleteWrapper = function(data, event) {
  var id = $(event.target).data("wrapper");
  
  // This will be the same as "data" argument
  var item = rootViewModel.items().filter(function(i) { return i.wrapper_id == id; })[0];
  
  rootViewModel.items.remove(item);
};

ko.applyBindings(rootViewModel);
&#13;
<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>

<ul data-bind="foreach: items">
  <li>
    <span data-bind="text: name"></span>
    <input type="checkbox" data-bind="checked: isChecked">
    <button data-bind="event: { click: $root.deleteWrapper }, attr: { 'data-wrapper': wrapper_id }">Delete</button>
  </li>
</ul>
&#13;
&#13;
&#13;

作为最后一个脚注,我已合并了@RoyJ's answer的简化(使用remove而不是splice删除)。

答案 2 :(得分:0)

我使用observableArray&#39; remove方法简化了JotaBe的第二个解决方案。

&#13;
&#13;
var item1 = { wrapper_id: 1, name: "Item ONE", isChecked: ko.observable(false) };
var item2 = { wrapper_id: 2, name: "Item TWO", isChecked: ko.observable(true) };
var item3 = { wrapper_id: 3, name: "Item THREE", isChecked: ko.observable(false) };

var rootViewModel = {
  items: ko.observableArray([item1, item2, item3])
};

rootViewModel.deleteWrapper = function(data) {
  rootViewModel.items.remove(data);
};

ko.applyBindings(rootViewModel);
&#13;
<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>

<ul data-bind="foreach: items">
  <li>
    <span data-bind="text: name"></span>
    <input type="checkbox" data-bind="checked: isChecked">
    <button data-bind="event: { click: $root.deleteWrapper }, attr: { 'data-wrapper': wrapper_id }">Delete</button>
  </li>
</ul>
&#13;
&#13;
&#13;