我被困在项目的一个特定部分,其中包含标题中提到的组件。
我目前有一个概念证明,它的工作方式与我希望的方式相同:
在我目前的情况下,我在应用程序启动时实例化viewmodels(如果我不实例化它们,Sammy将不会处理路由)。问题是Sammy加载和交换视图的位置。我必须调用ko.applyBindings来让KO绑定到视图。但反复呼吁申请的不良做法。
我的问题是,如何绑定我按需加载的视图?我无法调用ko.applybindings,因为当视图加载多次时会产生内存泄漏。
以下是一个示例VM,其中包含违规的ko.applyBindings:
function serviceInfoVm() {
var self = this;
self.ObjectKey = ko.observable();
self.Service = ko.observable();
self.LoadService = function () {
$.get('ServiceData/Detail', { serviceId: self.ObjectKey() }, function (data) {
self.Service(data);
});
};
$.sammy('#content', function () {
this.get('#/service/:id', function (context) {
var ctx = context;
self.ObjectKey(this.params['id']);
self.LoadService();
$.get('Content/ServiceInfo', function (view) {
ctx.app.swap(view);
ko.applyBindings(self);
});
});
}).run();
};
任何有这个问题的指针和/或解决方案的人?
答案 0 :(得分:3)
您在viewmodel中拥有Sammy代码,如果该视图模型将存在且您希望加载子视图模型和视图,则该代码可以正常工作。所以我认为这就是你要做的。深思熟虑......将sammy代码分离到自己的模块中(我称之为router.js中的路由器)并让它将导航与任何视图模型分开管理。
但回到你的代码......你可以设置子视图和子视图模型,并在调用sammy.get之前对它们使用applybindings。基本上,您提前注册路线。然后sammy.get只导航到新视图,该视图已经是数据绑定。
答案 1 :(得分:1)
不是解决方案,而是另一种方法:
放弃了动态加载视图的想法。 现在,我的视图始终显示在页面中,并且可见性由此代码触发:
var app = function () {
var self = this;
self.State = ko.observable('home');
self.Home = ko.observable(new homepageVm());
self.User = ko.observable(new userInfoVm());
$.sammy(function () {
this.get('#/', function (context) {
self.State('home');
});
this.get('#/info/:username', function (context) {
self.State('user');
self.User().UserName(context.params['username']);
self.User().LoadInfo();
});
}).run();
};
以这种方式触发div可见性:
<div id="homeView" data-bind="with: Home, visible: State() === 'home'">
这样,只需在应用启动时调用一次ko.applyBindings。 上面的viewmodel绑定到我们的shell页面。
有关此here
的更多信息答案 2 :(得分:0)
在返回的模板中的特定元素上调用applyBindings是一个选项:
ko.applyBindings(viewModel, htmlNode)
另请参阅有关延迟加载模板的此问题:knockout.js - lazy loading of templates
这里有关于applyBindings的文档:http://knockoutjs.com/documentation/observables.html