我是Knockout的新手,我正在构建一个实际上是大型计算器的应用程序。到目前为止,我在一个页面上运行了两个淘汰赛实例。一个例子工作得非常好,但是另一个例子完全被打破了,而且似乎根本没有注册?
下面是我的Javascript,fetchYear是完美无缺的功能,fetchPopulation是完全破坏的功能。它似乎没有注册" ageview"从HTML开始,我无法弄清楚。
错误:
未捕获的ReferenceError:无法处理绑定" foreach:function (){return ageView}"消息:未定义ageView
提前致谢。
JS:
var index = {
fetchYear: function () {
Item = function(year){
var self = this;
self.year = ko.observable(year || '');
self.chosenYear = ko.observable('');
self.horizon = ko.computed(function(){
if(self.chosenYear() == '' || self.chosenYear().horizon == undefined)
return [];
return self.chosenYear().horizon;
});
};
YearViewModel = function(yeardata) {
var self = this;
self.yearSelect = yeardata;
self.yearView = ko.observableArray([ new Item() ]);
self.add = function(){
self.yearView.push(new Item("New"));
};
};
ko.applyBindings(new YearViewModel(yearData));
},
fetchPopulation: function () {
popItem = function(age){
var self = this;
self.age = ko.observable(age || '');
self.chosenAge = ko.observable('');
self.population = ko.computed(function(){
if(self.chosenAge() == '' || self.chosenAge().population == undefined)
return [];
return self.chosenAge().population;
});
};
PopulationViewModel = function(populationdata) {
var self = this;
self.ageSelect = populationdata;
self.ageView = ko.observableArray([ new popItem() ]);
self.add = function(){
self.ageView.push(new popItem("New"));
};
};
ko.applyBindings(new PopulationViewModel(populationData));
}
}
index.fetchYear();
index.fetchPopulation();
HTML:
<div class="row" data-bind="foreach: yearView">
<div class="grid_6">
<img src="assets/img/index/calendar.png" width="120" height="120" />
<select class="s-year input-setting" data-bind="options: $parent.yearSelect, optionsText: 'year', value: chosenYear"></select>
<label for="s-year">Start year for the model analysis</label>
</div>
<div class="grid_6">
<img src="assets/img/index/clock.png" width="120" height="120" />
<select class="s-horizon input-setting" data-bind="options: horizon, value: horizon"></select>
<label for="s-horizon">Analysis time horizon</label>
</div>
</div>
<div class="row" data-bind="foreach: ageView">
<div class="grid_6">
<img src="assets/img/index/calendar.png" width="120" height="120" />
<select class="s-year input-setting" data-bind="options: ageSelect, optionsText: 'age', value: chosenAge"></select>
<label for="s-agegroup">Age group of <br> target population</label>
</div>
<div class="grid_6">
<img src="assets/img/index/clock.png" width="120" height="120" />
<input class="s-population input-setting"></input>
<label for="s-population">Size of your patient <br> population <strong>National</strong> </label>
</div>
</div>
答案 0 :(得分:17)
执行此操作时(在fetchYear
中):
ko.applyBindings(new YearViewModel(yearData));
您使用YearViewModel
视图模型绑定整个页面。但是YearViewModel
没有名为ageView
的属性,所以你得到错误并且淘汰停止尝试绑定任何其他内容。
您需要做的是通过将您想要的元素传递给ko.applyBindings
来限制绑定仅覆盖部分dom。例如:
<div class="row" id="yearVM" data-bind="foreach: yearView">
//....
<div class="row" id="popVM" data-bind="foreach: ageView">
然后:
ko.applyBindings(new YearViewModel(yearData), document.getElementById("yearVM"));
//...
ko.applyBindings(new PopulationViewModel(populationData), document.getElementById("popVM"));
现在,您的绑定仅限于实际显示该模型中的内容的DOM部分。
另一种方法是让您的两个视图模型作为父视图模型的一部分,然后您可以将绑定应用于整个页面。如果您需要混合来自两个VM的部件,并且在页面的不同部分中不方便地将它们分开,这将使其更容易。类似的东西:
var myParentVM = {
yearVM : index.fetchYear(), // note, make this return the VM instead of binding it
popVM : index.fetchPopulation(), // ditto
}
ko.applyBindings(myParentVM);
然后你就像这样声明你的绑定:
<div class="row" data-bind="foreach: yearVM.yearView">
答案 1 :(得分:2)
这不起作用的主要原因是因为你在一个页面上多次调用ko.applyBindings()(这不是真的被禁止但在我看来是不好的做法)。
如果你需要调用它两次,你必须用一个容器来调用它,这个容器应该绑定到哪个区域。
这样的事情:
ko.applyBindings(new YearViewModel(yearData), document.getElementById('YourYearViewElementId'));
你得到的错误来自第一个绑定,它试图处理整个页面而没有找到&#39; ageView&#39;在其ViewModel中。
如果您为单个页面构建单个ViewModel,那么如果需要,您可以使用子模型。
这种情况的一些伪代码:
var Section1ViewModel = function() {
var self = this;
self.property1 = ko.observable();
self.myComputed = ko.computed(function () {
// do some fancy stuff
});
self.myFunc = function() {
// do some more fancy stuff
};
}
var Section2ViewModel = function() {
var self = this;
self.property1 = ko.observable();
self.myComputed = ko.computed(function () {
// do some fancy stuff
});
self.myFunc = function() {
// do some more fancy stuff
};
}
var PageViewModel = function() {
var self = this;
self.section1 = ko.observable(new Section1ViewModel());
self.section2 = ko.observable(new Section2ViewModel());
self.myGlobalFunc = function() {
// do some even more fancy stuff
}
}
ko.applyBindings(new PageViewModel());
希望有所帮助。
祝你好运, 克里斯