问题 混合Knockout和服务器端渲染


我有一些页面需要通过服务器端呈现,以使它们对搜索引擎友好。对于搜索引擎,它应该作为经典网站。对于用户,我想让界面更具互动性。我的想法是呈现页面服务器端,然后使用knockout和jquery通过ajax再次获取数据并将其绑定到页面。

我担心没有内容或重复内容的闪烁。这样的案例是否有最佳实践/模式?

该过程如下所示:

  1. 使用服务器端渲染页面,包括一长串html元素。
  2. 使用jQuery获取已呈现给页面的相同数据。
  3. 使用jquery清除服务器端内容。
  4. 将ajax绑定到knockout模板,这有效地呈现了之前的页面。
  5. 普通用户随后点击浏览数据会使用ajax和knockout来呈现数据。
  6. 搜索引擎可以按照标准链接查看与用户相同的数据。

我想要的部分是如何使用knockout / jquery预渲染,清除和重新渲染。

也许我的思维过程有点偏差,我很想听到反馈。


10121
2017-09-18 15:26


起源

这是有风险的。如果您开始使您的网页专门针对搜索引擎,那么Google(以及其他人)会在您解决问题时降级。 - deltree
@deltree我不认为我从SEO的角度做错了什么。我只是为搜索引擎提供相同的ajaxed内容。如果你关闭了javascript,这也是你得到的相同内容。 - Darthg8r
@danludwig这不起作用,因为引擎不会索引内容,只是网址。 url的内容将变为空白到蜘蛛。 - Darthg8r


答案:


它可行,基本上从服务器端填充您的数据,但是将“数据绑定”属性添加到您的输入,从淘汰部分,通过获取字段值来设置您的可观察量。

这是一个简单形式的示例:

MVC部分:

public ActionResult Index()
{
    Person newPerson = new Person()
    {
        FirstName = "John",
        LastName = "Smith"
    };

    return View(newPerson);
}

而你的观点:

<div id="main">
    <div>
        First Name:
        @Html.TextBoxFor(p => p.FirstName, new { data-bind = "value: firstName" })
    </div>
    <div>
        Last Name:
        @Html.TextBoxFor(p => p.LastName, new { data-bind = "value: lastName"})
    </div>

    <input type="button" data-bind="click: showValues" value="Show" />
</div>

最后你的淘汰赛部分:

var personViewModel = function () {

    var self = this;

    self.firstName = ko.observable($("#FirstName").val());
    self.lastName = ko.observable($("#LastName").val());

    self.showValues = function () {
        alert(self.firstName() + " " + self.lastName());
    }
};

ko.applyBindings(new personViewModel());

希望适用于您的情况。

编辑:修复data_bind到数据绑定的错误


8
2018-06-28 12:01



这个答案应该标记为已接受 - Matthew James Davis


你可以尝试淘汰预渲染的绑定处理程序。它基本上完成了Tamim的建议,但它处理foreach并适用于任何数据绑定。

https://www.npmjs.com/package/knockout-pre-rendered

您还可以考虑使用“通用”的React - 您可以使用相同的代码在服务器和客户端上呈现页面。由于React使用diff-engine,当服务器呈现的内容被客户端呈现的内容替换时,不会闪烁。

http://facebook.github.io/react/

http://reactjs.net/


6
2018-06-17 11:30





您可以使用Node和像domino这样的简单DOM实现来渲染knockout:


1
2018-04-28 14:34





它也可以使用 peTemplate 捆绑。对于tempate和foreach绑定,它不会重新生成HTML,而是使用服务器端生成的HTML。您需要做的唯一事情是通过指定数据键的少数属性来注释服务器中的HTML。


0
2017-08-29 12:13





这用了 迪朗达尔 除了Knockout,但我有同样的问题,这是我提出的解决方案:

https://github.com/bestguy/durandal-delayed-composition


0
2018-01-04 07:07