Knockout选择更改事件未触发

时间:2016-08-05 11:46:09

标签: model-view-controller knockout.js

我有多个下拉列表绑定到我的项目视图模型 - 当用户在其他地方执行操作时,此集合会刷新。我遇到的问题是更改事件没有触发 -

                <div id="case-pin-@modelItem.CaseID" class="row hidden popovercontainer pinBinding">
                    <select id="pingroup_@modelItem.CaseID"
                            data-bind="options: userPins, optionsCaption:'-- please select --', optionsText: 'Name', optionsValue: 'Id', event: { change: function(data, event) { pinChanged(data, event,'@modelItem.CaseID') } }"></select>
                </div>

我已尝试订阅(但这不适用于指定的optionsCaption)以及事件。

function UserPinViewModel() {
    var self = this;
    self.userPins = ko.observableArray([]);
    //self.selectedPin = ko.observable();

    //self.selectedPin.subscribe(function(newValue) {
    //    console.log(newValue);
    //});

    self.pinChanged = function (data, event, caseId) {
        alert(caseId);
    }
}

var objPin;

$(function () {
    objPin = new UserPinViewModel();

    $(".pinBinding").each(function () {
        ko.cleanNode(this);
        ko.applyBindings(objPin, this);
    });
})

我需要使用事件而不是订阅的原因是因为我需要标识符来确定下拉列表已被更改的实体以及所选的新值。

修改

因此,根据提供的评论修改了代码,但订阅中的警报仍未触发......

function UserPinViewModel(caseId) {
    var self = this;
    self.userPins = ko.observableArray([]);
    self.selectedPin = ko.observable();
    self.caseId = caseId;

    self.selectedPin.subscribe(function (newValue) {
        alert(newValue);
    });
}

var pinObjs = [];

$(function () {
    pinObjs = [];

    $(".pinBinding").each(function () {
        var caseId = this.getAttribute("data-caseid");
        var view = new UserPinViewModel(caseId);
        pinObjs.push(view);

        ko.cleanNode(this);
        ko.applyBindings(view, this);
    });
})

订阅中的提醒不会被触发......

                <div id="case-pin-@modelItem.CaseID" data-caseid="@modelItem.CaseID" class="row hidden popovercontainer pinBinding">
                    <select data-bind="options: userPins,
                            optionsCaption:'-- please select --',
                            optionsText: 'Name',
                            optionsValue: 'Id',
                            value: selectedPin"></select>
                </div>

1 个答案:

答案 0 :(得分:1)

我不认为使用event绑定是可行的方法。对我来说,为每个选择框创建一个视图模型似乎是合乎逻辑的。然后,您可以将CaseID属性存储在viewmodel中,而不是尝试通过绑定访问它。如果这适合你的工作方式,你仍然可以通过DOM“注入”它。

接近目前的做法,你可以这样做:

<div id="case-pin-@modelItem.CaseID" data-caseid="@modelItem.CaseID">...</div>

$(".pinBinding").each(function () {
    var caseId = this.getAttribute("data-caseid");
    var vm = new UserPinViewModel(caseId);

    ko.cleanNode(this);
    ko.applyBindings(vm, this);
});

使用修改后的viewmodel:

function UserPinViewModel(caseId) {
  var self = this;

  self.userPins = ko.observableArray([]);
  self.selectedPin = ko.observable();

  self.selectedPin.subscribe(function(newValue) {
    console.log(newValue, caseId);
  });
}

options绑定可以与value一起使用,因为caseId之前已传递给viewmodel。

<select data-bind="options: userPins, 
                   optionsCaption:'-- please select --', 
                   optionsText: 'Name', 
                   optionsValue: 'Id',
                   value: selectedPin"></select>

请注意,如果要在选择框之间共享selectedPinuserPins属性 ,则必须创建由viewmodels共享的observable,但在其他地方初始化......

修改:您的更新代码似乎有效......

function UserPinViewModel(caseId) {
  var self = this;
  self.userPins = ko.observableArray([{
    Name: "Pin 1",
    Id: "1"
  }, {
    Name: "Pin 2",
    Id: "2"
  }]);
  self.selectedPin = ko.observable();
  self.caseId = caseId;

  self.selectedPin.subscribe(function(newValue) {
    alert("Pin:" + newValue + ", case: " + self.caseId);
  });
}

var pinObjs = [];

$(function() {
  pinObjs = [];

  $(".pinBinding").each(function() {
    var caseId = this.getAttribute("data-caseid");
    var view = new UserPinViewModel(caseId);
    pinObjs.push(view);

    ko.cleanNode(this);
    ko.applyBindings(view, this);
  });
})
<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 id="case-pin-@modelItem.CaseID" data-caseid="testCaseId1" class="row hidden popovercontainer pinBinding">
  <select data-bind="options: userPins,
                     optionsCaption:'-- please select --',
                     optionsText: 'Name',
                     optionsValue: 'Id',
                     value: selectedPin"></select>
</div>

<div id="case-pin-@modelItem.CaseID" data-caseid="testCaseId2" class="row hidden popovercontainer pinBinding">
  <select data-bind="options: userPins,
                     optionsCaption:'-- please select --',
                     optionsText: 'Name',
                     optionsValue: 'Id',
                     value: selectedPin"></select>
</div>