knockout.js 敲除js:有条件地绑定标题属性

8xiog9wr  于 2022-11-10  发布在  其他
关注(0)|答案(2)|浏览(148)

我在屏幕的顶部有几个标签,可以将用户导航到程序的几个部分。如果程序的某个部分有紧急通知,那么其中的一个标签现在应该会突出显示。
我在#main-header中添加了一个'notifications'属性,它是整个顶部div的id。
css唯一的项目正在相应地改变,到目前为止一切顺利。
不过,我需要添加文本到标题属性只有当有任何通知的用户。它是被检查每10分钟,如果有任何通知。
这个顶层菜单是在一个循环中创建的,在html中看起来如下所示:

<ul id="navigationMenuTop" class="nav navbar-nav" data-bind="foreach: getRoutes">
        <li data-bind="css: { active: isActive() }, attr: { title: hash === '#url/location' ? setNotificationTitle : '' }">
            <a data-bind="attr: { href: hash }, html: displayName"></a>

在视图模型中:

var self = this;
        self.setNotificationTitle = ko.computed(function () {
            var attr = $("#main-header").attr("notifications");
            if (typeof attr !== 'undefined' && attr !== false) {
                return "NotificationAlert";
            } else {
                return "";
            }
        });

它是在以下帮助下创建的:Knockout.js: conditionally bind title attribute of div
问题是使用setNotificationTitle会导致我在顶部根本看不到标签。当我简单地在html中硬编码文本时,顶部菜单会显示出来,工具提示也会工作。
我错过了什么?
Edit:视图现在如下所示:

<ul id="navigationMenuTop" class="nav navbar-nav" data-bind="foreach: getRoutes">
        <li data-bind="css: { active: isActive() }, attr: { title: hash === '#url/location' ? notificationTitle : '' }">
            <a data-bind="attr: { href: hash }, html: displayName"></a>

和视图模型:

var self = this;
    self.notificationTitle = ko.observable("");

    self.setNotificationTitle = ko.computed(function () {
        var attr = $("#main-header").attr("notifications");
        if (typeof attr !== 'undefined' && attr !== false) {
            self.notificationTitle("NotificationAlert");
        } else {
            self.notificationTitle("");
        }
    });

每当检查是否有任何通知时,都会调用setNotificationTitle。这也会给我同样的结果。
EDIT:不确定是否重要,但在视图模型的底部,它返回NavigationViewModel,如

return NavigationViewModel;

将其更改为我在knockout js文档中看到的内容

return NavigationViewModel = {
    notificationTitle: this.notificationTitle
};

结果在浏览器中的错误为我在系统的东西,因为notificationTitle是未定义的,它不是...

hsgswve4

hsgswve41#

问题是您使用并更新DOM来存储状态,knockout无法知道您何时修改了该状态。
假设您的页面上有一个元素:

<div id="stateEl" data-state="1">...</div>

您可以编写一个可以正常工作的淘汰测试绑定:

<div data-bind="text: document.getElementById('stateEl').dataset.state"></div>

当您呼叫ko.applyBindings时,这个项目会将“1”呈现至页面。

**但是,**如果您在调用ko.applyBindings之后 * 更改了第一个元素的属性,knockout的文本绑定将不会更新。数据绑定依赖于ko.observable属性; knockout没有提供订阅DOM更改的机制。

因此,无论何时执行此操作:

document.getElementById("stateEl").dataset.state = 2;

挖空元素仍将渲染“1”。

可能的解决方案

有很多可能的解决方案,有些比其他更激烈。我将按照我个人的喜好列出一些:

    • 不要通过jQuery或任何其他javascript代码直接访问或修改DOM *。例如:通过挖空视图模型运行定期更新,并使用在挖空中运行良好的模式来共享要显示的数据。
  • 确保您的视图模型示例可供外界访问,并确保更新代码将任何新信息通知给它。
  • 在视图模型中实现额外的定时更新,每隔x秒从DOM读取一次

下面是第二个解决方案的示例:
第一个

ny6fqffe

ny6fqffe2#

最后,通过添加该可观察项和在检查是否存在任何通知期间调用的该函数来解决该问题。

self.notificationTitle = ko.observable("");

        self.setNotificationTitle = function () {
            var attr = $("#main-header").attr("notifications");
            if (typeof attr !== 'undefined' && attr !== false) {
                self.notificationTitle("NotificationAlert");
            } else {
                self.notificationTitle("");
            }
        };

然后这样补充道:

<li data-bind="css: { active: (isActive() }, attr: { title: $parent.notificationTitle }">

相关问题