如何在标题中对元内容使用数据绑定?

时间:2018-06-13 15:01:01

标签: knockout.js meta-tags

我有一个页面上的项目列表,选中后会将用户带到该特定项目页面。每个页面都需要一个带有项目名称和编号的元标记。为每个项目生成的页面是动态的。我一直试图使用Knockout绑定而没有运气。

<meta name="DocumentType" content="ITEM">
<meta name="Number" data-bind="text: itemNumber">
<meta name="Name" data-bind="text: itemName">

在本页的其余部分,我一直使用视图模型和applyBindings成功使用数据绑定。我已将itemName和itemNumber包含在视图模型中,因此它们将返回结果。此时,如何将数据绑定到我的元标记?

我尝试使用attr标记跟踪Knockout的文档:http://knockoutjs.com/documentation/attr-binding.html

我还试图在这里做绑定到html标题的操作: Is there a way to set the page title by data-binding using Knockout.js?

我没有运气好。我可能做错了,但感谢任何帮助。

2 个答案:

答案 0 :(得分:0)

您应该能够将数据绑定应用于任何DOM元素。您没有提供如何调用ko.applyBindings,但是我在自己的项目中使用的是这样的:

ko.applyBindings(pageModel, document.getElementsByTagName('html')[0]);

通过将顶级HTML元素传递给它,在下面找到的所有dom元素都应绑定到数据绑定元素。

答案 1 :(得分:0)

我通过将数据绑定应用于head元素解决了这个问题,或者您也可以将其应用于html元素,如Chris Knoll在先前的回答中所述。

然后继续将“文本”绑定添加到title元素:

<title data-bind="text: title"></title>

要将值绑定到meta标签的content属性,我创建了一个自定义绑定:

// extra custom binding to bind content attribute of meta element
ko.bindingHandlers.metaContent = {
    update: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
        // This will be called once when the binding is first applied to an element,
        // and again whenever any observables/computeds that are accessed change
        // Update the DOM element based on the supplied values here.
        let contentAttribute = 'content';
        if (contentAttribute in element) {
            let value = valueAccessor();
            let valueUnwrapped = ko.unwrap(value);

            if (valueUnwrapped)
                element.content = valueUnwrapped;
        }
    }
};

具有使用自定义绑定的content属性的数据绑定的meta元素:

<meta name="description" data-bind="metaContent: description" />

为了完整起见,我的视图模型:

export class Head {
    public title: KnockoutObservable<string> = ko.observable("My title");        
    public description: KnockoutObservable<string> = ko.observable("My description");

    constructor() {            
        ko.applyBindings(this, $("head")[0]);
    }
}