我有两种类型的活动:
function Activity(type, name) {
this.Type = type
this.Name = ko.observable(name)
}
function MeetingActivity(name, place) {
Activity.call(this, 1500, name)
this.Place = ko.observable(place)
}
function TeachingActivity(name, place, teacherId) {
Activity.call(this, 1600, name)
this.Place = ko.observable(place)
this.TeacherId = ko.observable(teacherId)
}
并尝试将不同类型的活动绑定到某个容器,如下所示:
Activity:
<select data-bind='value: ActivityTypeId'>
<option value='1500'>Meeting</option>
<option value='1600'>Teaching</option>
</select>
<div data-bind='if: ActivityTypeId()==1500'>
<div data-bind='with: Activity'>
<span data-bind='text:Name'></span>
<span data-bind='text:Place'></span>
</div>
</div>
<div data-bind='if: ActivityTypeId()==1600'>
<div data-bind='with: Activity'>
<span data-bind='text:Name'></span>
<span data-bind='text:Place'></span>
<span data-bind='text:TeacherId'></span>
</div>
</div>
我写了this fiddle来完成工作,但没有运气,我做错了什么?
答案 0 :(得分:0)
您提供的小提琴错误来自subscribe
ActivityTypeId
方法。请注意,在创建function
时,this
会被当前的函数范围覆盖,因此Activity
现在会丢失在您当前的this
中。
function ViewModel() {
this.ActivityTypeId = ko.observable(1500);
this.Activity = ko.observable(new MeetingActivity('meeting 1', 'g12', 155))
this.ActivityTypeId.subscribe(function(typeId) {
if (typeId == 1500) this.Activity(new MeetingActivity('meeting 1', 'g12'))
else if (typeId == 1600) this.Activity(new TeachingActivity('meeting 2', 'g13', 155))
})
}
要修复它,您可以将其分配给另一个变量并通过它访问活动。像:
function ViewModel() {
var self = this; //this is what i meant in assigning in another variable
this.ActivityTypeId = ko.observable(1500);
this.Activity = ko.observable(new MeetingActivity('meeting 1', 'g12', 155))
this.ActivityTypeId.subscribe(function(typeId) {
if (typeId == 1500) self.Activity(new MeetingActivity('meeting 1', 'g12')) //use self on accessing Activity
else if (typeId == 1600) self.Activity(new TeachingActivity('meeting 2', 'g13', 155)) //use self on accessing Activity
})
}
答案 1 :(得分:0)
original fiddle的问题在于您更新了Activity
以包含新类型,并且显示更改为显示该类型,但是包含类型的时间和预期显示的类型不一样。
为了确保没有同步问题,您应该在Activity.Type
(应该是可观察的)上进行测试。此外,不是让Activity
成为可观察的并且订阅更改其值,而是将其设为计算值。
function Activity(type, name) {
this.Type = ko.observable(type)
this.Name = ko.observable(name)
}
function MeetingActivity(name, place) {
Activity.call(this, 1500, name)
this.Place = ko.observable(place)
}
function TeachingActivity(name, place, teacherId) {
Activity.call(this, 1600, name)
this.Place = ko.observable(place)
this.TeacherId = ko.observable(teacherId)
}
function ViewModel() {
var self = this
self.ActivityTypeId = ko.observable(1500);
self.Activity = ko.computed(
function() {
var typeId = +self.ActivityTypeId();
if (typeId == 1500) return new MeetingActivity('meeting 1', 'g12');
else if (typeId == 1600) return new TeachingActivity('meeting 2', 'g13', 155);
else console.warn('Type ID:', typeId);
});
}
var VM = null
$(document).ready(function() {
VM = new ViewModel()
ko.applyBindings(VM)
console.log(VM)
})
<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>
Activity:
<select data-bind='value: ActivityTypeId'>
<option value='1500'>Meeting</option>
<option value='1600'>Teaching</option>
</select>
<div data-bind="with: Activity">
<div data-bind='if: Type()==1500'>
<span data-bind='text:Name'></span>
<span data-bind='text:Place'></span>
</div>
<div data-bind='if: Type()==1600'>
<span data-bind='text:Name'></span>
<span data-bind='text:Place'></span>
<span data-bind='text:TeacherId'></span>
</div>
</div>