Knockout JS从foreach中抛出“not a function”错误

时间:2016-06-10 17:44:41

标签: javascript function knockout.js

我在Knockout面临以下问题。我有一个列表设置,其中填充了一些值。这一切都很好,我得到我的下拉项目就好了。它还有一个click函数,用于记录被点击的值。这适用于console.log但它绝对拒绝更新我设置的KO observable。如果我将HTML中的<ul>行移出<a>到页面的其他部分,它只会在<ul>内进行搞定,它可以正常运行。同样,如果我告诉Javascript更新“dropdownSelectedA3”值,如果点击了不同的按钮。我在想它正在寻找错误的地方或其他什么,但我似乎无法解决这个问题。

也尝试过:

  • 将“this.dropdownSelectedA3(answerUserA3)”更改为“viewmodel.dropdownSelectedA3(answerUserA3)”但发生同样的问题
  • 不幸的是,删除$ parent也无法修复它

有人可能指出我的错误吗?

我的代码:

相关HTML:

<ul class="dropdown-menu" aria-labelledby="dropdownMenu3UL" data-bind="foreach: dropdownAnswersAssignment3">
         <li>
           <a data-bind="text: $data, click: $parent.logAnswerA3" href="#"></a>
         </li>
        </ul>

相关JS(在我的viewmodel中):

this.dropdownAnswersAssignment3 = ko.observableArray([C1M5OptionsActive.A3.option1, C1M5OptionsActive.A3.option2, C1M5OptionsActive.A3.option3, C1M5OptionsActive.A3.option4]);

var answerUserA3

this.dropdownSelectedA3 = ko.observable("...");

this.logAnswerA3 = function(answer) {
    answerUserA3 = answer;
    this.dropdownSelectedA3(answerUserA3)
}

2 个答案:

答案 0 :(得分:0)

如果要在foreach循环中绑定click事件,则需要在VM中存在数组所在的单击函数,或者通过嵌套View模型将其引用到父视图模型在这种情况下,您可以将click event引用到您的父虚拟机。事实上,对于数组的每个元素,您创建一个新的itemViewModel实例,然后每个实例都指向父点击功能
示例:https://jsfiddle.net/9aLvd3uw/234/

HTML:

<ul data-bind="foreach: dropdownAnswersAssignment3">
   <li>
        <a data-bind="click:$parent.logAnswerA3,text: name"></a>
   </li>
</ul> 

JS:

var itemViewModel = function(text){
 var self = this;
 self.name = ko.observable(text); 
}
function demoViewModel() {
  var self = this;
  //fake data
    var arr =  [ 'Click A', 'Click B', 'Click C'];
   self.logAnswerA3  = function (item){
     alert(item.name() + " just Cliked");
   }
   self.dropdownAnswersAssignment3 = ko.observableArray($.map(arr, function (element) {
        return new itemViewModel(element);
    }));
}
var mm = new demoViewModel();

ko.applyBindings(mm);

答案 1 :(得分:0)

如果我理解你的问题,你只需要在点击它时将列表的对象放在一个observable中。你可以这样:

var ViewModel = function() {
  var self = this;

  self.objectClicked = ko.observable("...");
  self.objectList = ko.observableArray(["Object 1", "Object 2", "Object 3"]);

  self.click = function(data) {
    self.objectClicked(data);
  }
}

var viewModel = new ViewModel();
ko.applyBindings(viewModel);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

<ul data-bind="foreach: objectList">
  <li>
    <a data-bind="text: $data, click: $root.click"></a>
  </li>
</ul>
<p data-bind="text: $root.objectClicked"></p>