Knockout是在Magento 2的前端使用的javascript库。它实现了Model-View-View Model(MVVM)设计模式。几乎每一页都可以找到Magento 2中的Knockout,它最常出现的地方是结帐页面,这是Magento 2中最复杂的实现。

这篇博客的目的是解释如何在Magento 2中有效使用的KO模型视图和视图。

我们将演示如何实现非常简单的逻辑,并尝试解释基本概念。

如果您不熟悉Knockout库,我建议您点击阅读文档:http//knockoutjs.com/documentation/introduction.html

在我们的示例中,所有文件都位于“Magease_Js”模块中。对于当前实例,我们在文件“koexample.js”中创建了View-Model,位于:app/code/Magease/Js/view/frontend/web/js/koexample.js

我们的View-Model示例如下:

define(['uiComponent'], function(Component) {
 
        return Component.extend({
            initialize: function () {
                this._super();
		this.sayHello = "Hello this is content populated with KO!";
            }
        });
});

我们的View-Model具有依赖性'uiComponent'(Magento_Ui/js/lib/core/collection.js)。UiComponent从“ uiElement ”Magento_Ui/js/lib/core/element/element.js)继承类和方法,在最后一个类中,我们的View-Model实现了Knockout的逻辑。

如果你打开“Magento_Ui/js/lib/core/element/element.js”,你会发现ko对象是来自requireJS的define函数中的依赖:

define(['ko', 'underscore', 'mageUtils', 'uiRegistry', 'uiEvents', 'uiClass', './links', '../storage'],
function (ko, _, utils, registry, Events, Class, links) {
    'use strict';
....

View-Model应填充一些html内容或V视图。为此,我们在phtml文件中创建了非常简单的View

<div data-bind="scope: 'koexample'">
<!-- ko template: getTemplate() --><!-- /ko -->
</div>
 
<script type="text/x-magento-init">
        {
            "*": {
                "Magento_Ui/js/core/app": {
                    "components": {
                        "koexample": {
                            "component": "Magease_Js/js/koexample",
                            "template" : "Magease_Js/example"
                        }
                    }
                }
            }
        }
</script>

在我们的示例中,我们使用了Knockout模板文件example.html,其中包含下一个内容(模板文件在“template”上面的代码中定义:“Magease_Js / example”)。模板文件由javascript动态加载。

在我们的示例中,我们使用了Knockout模板文件示例。html,其中包含下一个内容(模板文件在“template”之上的代码中定义:“Magease_Js/example”)。模板文件是由javascript动态加载的。

<p>I am template located on: app/code/Magease/Js/view/frontend/web/template/example.html and dynamically loaded. This is my message to you:</p>
<p data-bind="text: sayhello"></p>

激活Knockout后,您的视图应显示:

<p>I am template located on: app/code/Magease/Js/view/frontend/web/template/example.html, dynamically loaded. This is my message to you:</p>
<p data-bind="text: sayhello">Hello this is content populated with KO!</p>

Knockout的一个重要优势是,当View-Model发生变化时,KO会自动更新您的内容。为了自动更新内容,您应该在View-Model类中声明属性为observable

我们将用“this”来演示可观察逻辑。视图模型中的time属性。最好的解释是关于工作示例的。

define(['uiComponent'], function(Component) {
 
        return Component.extend({
            initialize: function () {
                this._super();
                this.time = Date();
                //time is defined as observable
                this.observe(['time']);
                //periodically updater every second
                setInterval(this.flush.bind(this), 1000);
            },
            flush: function(){
                this.time(Date());
            }
        });
});

在“initilalize”方法中,我们创建了属性“time”,并使用方法“ this.observe(['time']) ” 声明为observable 

这个“观察”方法来自“Magento_Ui/js/lib/core/element/element”类。如果要检查整个逻辑,请打开此文件并查找方法“observe”。

使用javascript函数“setInterval”,我们定期用新值更新属性“time”。这意味着KO应该使用新值自动更新View。

还有一件事,你应该修改你的View(ko模板文件),它应该如下所示:

<p>I am example3.HTML template, dynamically loaded. This is my message to you:</p>
<p data-bind="text: time"></p>

当您激活Knockout时,html / content应该每秒更新一次。Html应该如下所示:

<div data-bind="scope: 'koexample'">
<!-- ko template: getTemplate() --><p>I am example3.HTML template, dynamically loaded. This is my message to you:</p>
<p data-bind="text: time">Mon Mar 07 2016 12:58:30 GMT+0100 (CET)</p><!-- /ko -->
</div>

Knockout使用observable每秒更新一次。