我在主版面中有一个标题,每个页面都有内容。主布局有自己的视图模型,每个页面中的每个内容都有自己的模型。
我遇到的问题是当我尝试更新用户配置文件时,由于两个视图模型已分离,因此更改未反映在标头中。当我更新配置文件时,如何使标题立即反映实例?
// Header View Model (serve from Master Layout)
function HeaderViewModel() {
var self = this;
self.headerusername = ko.observable();
self.headerprofileImage = ko.observable(); // base 64 image
}
ko.applyBindings(new HeaderViewModel(), document.getElementById('header');
// Profile View Model (profile.html)
function ProfileViewModel() {
var self = this;
self.username = ko.observable();
self.profileImage = ko.observable(); // base 64 image
}
ko.applyBindings(new ProfileViewModel(), document.getElementById('profile');
<!-- Header (serve from master layout) -->
<header id="header">
<span data-bind="text:headerusername"></span>
<img data-bind="attr: {src:headerprofileImage }">
</header>
<!-- Update profile (profile.html) -->
<form id="profile>
<input type="text" data-bind="value:username">
<input type="file" data-bind="value:profileImage">
<button type="submit">Save</button>
</form>
答案 0 :(得分:1)
您可以使用ko.contextFor(element)
从配置文件视图模型的方法中使用以下代码访问标题的binding context:
var headerContext = ko.contextFor(document.getElementById('header'));
headerContext.$data.headerusername(self.username());
headerContext.$data.headerprofileImage(self.profileImage());
答案 1 :(得分:1)
我通常使用viewModel
在其自己的模块中组织每个require.js
。
然后我将定义一个单独的组件模块(一个总是返回同一个类的实例的模块),称为ProfileService
,作为共享的配置文件数据。
HeaderViewModel
和ProfileViewModel
都需要ProfileService
。
ProfileService
可以包含与API接口的方法,并且可以公开username
和profileImage
个可观察对象。
HeaderViewModel
和ProfileViewModel
会从ProfileService
导入共享的观察值:
档案ProfileService
:
define(function() {
function ProfileService() {
var self = this;
self.username = ko.observable();
self.profileImage = ko.observable();
// logic to retrieve/update data
}
return new ProfileService();
});
档案ProfileViewModel
:
define(['path/to/ProfileService', 'path/to/knockout.js'], function(ProfileService, ko) {
function ProfileViewModel() {
var self = this;
self.username = ProfileService.username;
self.profileImage = ProfileService.profileImage;
}
ko.applyBindings(new ProfileViewModel(), document.getElementById('profile');
});
[编辑]
正如@Kal_Torak的评论中所建议的,你可以在没有require.js
的情况下实现类似的东西,只需在全局命名空间中共享数据。类似的东西:
window.ProfileService = {
username: ko.observable(),
profileImage: ko.observable()
}
但如果您还不知道require.js
,我建议您抽出时间尝试一下。