Javascript 有没有办法通过使用Knockout.js进行数据绑定来设置页面标题?
我有一个带有Javascript 有没有办法通过使用Knockout.js进行数据绑定来设置页面标题?,javascript,html,knockout.js,Javascript,Html,Knockout.js,我有一个带有标题属性的viewModel。我想使用该属性设置页面标题。以下是我已经尝试过的,但没有成功: <html> <head> <title data-bind="text: Title"></title> </head> <body> <span data-bind="text: Title"/> <!-- this displays the title properly --&g
标题
属性的viewModel。我想使用该属性设置页面标题。以下是我已经尝试过的,但没有成功:
<html>
<head>
<title data-bind="text: Title"></title>
</head>
<body>
<span data-bind="text: Title"/> <!-- this displays the title properly -->
</body>
浏览器标题为空/默认值,而不是my
title
属性的值。尝试为html元素指定一个id
<html id="htmlTop" xmlns="http://www.w3.org/1999/xhtml">
编辑
这对我有用;我刚刚运行了这个页面,标题是“你好”。仔细检查你的代码是否有拼写错误
<html id="htmlTop">
<head>
<title data-bind="text: title"></title>
<script type='text/javascript' src='jquery.min.js'></script>
<script type='text/javascript' src='knockout-1.2.1.js'></script>
<script type="text/javascript">
$(function () {
var viewModel = { title: "Hello" };
ko.applyBindings(viewModel, document.getElementById("htmlTop"));
});
</script>
</head>
<body>
</body>
</html>
$(函数(){
var viewModel={title:“Hello”};
applyBindings(viewModel,document.getElementById(“htmlTop”);
});
截图:
您可以在更新时创建一个设置
文档。title
,然后将绑定添加到body
元素。根据@Douglas的建议,我的解决方案是在body的某个位置添加一个隐藏的div
,绑定到计算值:
<div data-bind="text: currentPageTitle()"></div>
这对我来说非常有效在我看来,这种情况需要一个可观察的订阅
...
<title>{FALL BACK TEXT}</title>
...
编辑:作为对我先前答案的修正,我想提出以下内容。我以前的建议行吗?是的,它工作得很好。然而,视图模型中的DOM操作本身并不“完全”遵循MVVM范式。实际的“最佳”方法是创建一个自定义绑定,该绑定在更新特定的可观察对象时设置文档标题
最后是我们闪亮的自定义绑定,用于“侦听”对可观察对象的更改(注意仅使用更新操作)
乍一看,这个解决方案的可伸缩性可能较差,但请记住,我们可以使用“call()”创建带有淘汰视图模型的“伪继承” 您可以使用淘汰订阅:
function viewModel() {
var self = this;
self.title = ko.observable(null);
self.title.subscribe(function(newTitle) {
document.title = newTitle;
})
}
var vm = new viewModel();
ko.applyBindings(vm);
vm.title('Hello page');
@拜伦-对不起-我还有最后一个主意,那我想水库会干涸的:)---看到了吗edit@ByronSommardahl传递HTML元素,而不仅仅是文档,怎么样?类似于
document.getElementsByTagName(“html”)
.Perfect的东西。我想还有一个问题妨碍了你。这绝对有效!谢谢。我通过使用:ko.applyBindings(viewModel,document.getElementsByTagName('html')[0]),在不向元素添加id的情况下实现了这一点希望这能简化您的答案。我使用了更通用的解决方案document.documentElement
,我不想继续编辑我的答案-有没有可能把它放在您的html标签上有效<代码>另外,能否将ViewModel上的Title属性绑定到更普通的对象(如span)上,并将其显示出来?我对代码进行了一些更新。是的,我可以成功地在其他地方绑定标题
。只有页面标题不起作用。@Adam,我在html元素上尝试了数据绑定,但也不起作用。我更新了我的答案-我写的应该可以-我只是测试了一下。看看我上面链接的页面上的最后一个示例,hasFocus。这将是非常类似的,除了您不需要init
,并且更新将document.title
设置为ko.utils.unwrapObservable(value)
而不是在if
块中使用它。这对我有用!当您不想用KO标记污染页面标题时,这是一种特别方便的方法,而KO标记只会在少数特定情况下动态使用。
...
<title>{FALL BACK TEXT}</title>
...
ViewModel = function() {
var self = this;
self.PageTitle = ko.observable(null);
self.PageTitle.subscribe(function(newValue){ document.title = self.PageTitle() });
//change PageTitle to see your handy work in action
self.PageTitle("Hello World!");
};
...
<title data-bind="htmlDocumentTitle: PageTitle()">{FALLBACK TEXT}</title>
...
ViewModel = function() {
var self = this;
self.PageTitle = ko.observable(null);
self.init = function(){
self.PageTitle("My page title from an obersvable");
};
//init the viewmodel
self.init();
};
ko.bindingHandlers.htmlDocumentTitle = {
update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
var fallbackTitle = "My document title";
var title = ko.unwrap(valueAccessor());
if(!title || title == null && title == "")
title = fallbackTitle;
document.title = title;
}
};
function viewModel() {
var self = this;
self.title = ko.observable(null);
self.title.subscribe(function(newTitle) {
document.title = newTitle;
})
}
var vm = new viewModel();
ko.applyBindings(vm);
vm.title('Hello page');