Magento 2 áp dụng ràng buộc KnockoutJS như thế nào


19

Theo một cách đọc rất khó hiểu về tài liệu KnockoutJS, việc khởi tạo một khung nhìn Knockout rất cơ bản trông giống như sau

// This is a simple *viewmodel* - JavaScript that defines the data and behavior of your UI
function AppViewModel() {
    this.firstName = "Bert";
    this.lastName = "Bertington";
}

// Activates knockout.js
ko.applyBindings(new AppViewModel());

tức là - bạn tạo một hàm javascript dự định được sử dụng như một hàm tạo đối tượng, khởi tạo một đối tượng từ nó và sau đó chuyển đối tượng đó vào ko.applyBindingsphương thức của đối tượng loại bỏ toàn cục ( ko)

Tuy nhiên, trong Magento 2, nếu bạn tải trang phụ trợ với Giao diện người dùng lưới, Magento sẽ khởi tạo js/core/app.jsmô-đun RequireJS

/**
 * Copyright © 2016 Magento. All rights reserved.
 * See COPYING.txt for license details.
 */
define([
    './renderer/types',
    './renderer/layout',
    'Magento_Ui/js/lib/ko/initialize'
], function (types, layout) {
    'use strict';

    return function (data) {
        types.set(data.types);
        layout(data.components);
    };
});

Đến lượt mình, Magento_Ui/js/lib/ko/initializemô-đun này tải mô-đun, xuất hiện để khởi tạo việc sử dụng KnockoutJS của Magento. Tuy nhiên, nếu bạn nhìn vào nguồn của mô-đun khởi tạo.

define([
    'ko',
    './template/engine',
    'knockoutjs/knockout-repeat',
    'knockoutjs/knockout-fast-foreach',
    'knockoutjs/knockout-es5',
    './bind/scope',
    './bind/staticChecked',
    './bind/datepicker',
    './bind/outer_click',
    './bind/keyboard',
    './bind/optgroup',
    './bind/fadeVisible',
    './bind/mage-init',
    './bind/after-render',
    './bind/i18n',
    './bind/collapsible',
    './bind/autoselect',
    './extender/observable_array',
    './extender/bound-nodes'
], function (ko, templateEngine) {
    'use strict';

    ko.setTemplateEngine(templateEngine);
    ko.applyBindings();
});

Bạn thấy Magento được gọi là ko.applyBindings();đối tượng mà không có đối tượng xem . Điều này không có ý nghĩa gì, và tôi không chắc liệu đó là sự hiểu biết hạn chế của tôi về Knockout hay Magento đang làm điều gì đó tùy chỉnh / lạ ở đây.

Đây có phải là nơi Magento thực sự áp dụng các ràng buộc Knockout? Hay điều đó xảy ra ở một nơi khác? Hay là Magento đang làm một cái gì đó khó khăn để chặn mã Knockout và xử lý nó ở nơi khác?

Câu trả lời:


38

Các Magento_Ui/js/lib/ko/initializethư viện là, thực sự, nơi Magento khởi dụ Knockout của nó. Magento không chỉ định ViewModel khi áp dụng các ràng buộc.

Khóa bị thiếu ở đây là ràng buộc KnockoutJS tùy chỉnh có tên scope.

Khi phiên bản Knockout của Magento gặp phải một scope:ràng buộc như thế này

<li class="greet welcome" data-bind="scope: 'customer'">
    <span data-bind="text: customer().fullname ? $t('Welcome, %1!').replace('%1', customer().fullname) : 'Default welcome msg!'"></span>
</li>

Nó nhận giá trị của liên kết đó (được đặt tên customer) và sử dụng nó để tải và áp dụng ViewModel cho các nút bên trong từ uiRegistry. Bạn có thể gỡ lỗi dữ liệu bị ràng buộc cho một phạm vi cụ thể với một số pregỡ lỗi KnockoutJS đơn giản

<div data-bind="scope: 'someScope'">
    <pre data-bind="text: ko.toJSON($data, null, 2)"></pre>            
</div>

Đây uiRegistrylà một từ điển đơn giản như đối tượng, được triển khai trong Magento_Ui/js/lib/registry/registrymô-đun RequireJS.

vendor/magento/module-ui/view/base/requirejs-config.js
17:            uiRegistry:     'Magento_Ui/js/lib/registry/registry',

Các đối tượng được đưa vào sổ đăng ký thông qua các bit của javascript trông như thế này

<script type="text/x-magento-init">
{
    "*": {
        "Magento_Ui/js/core/app": {
            "components": {
                "customer": {
                    "component": "Magento_Customer/js/view/customer",
                    "extra_data_1":"some_value",
                    "more_extra":"some_other_value",
                }
            }
        }
    }
}
</script>

Chương trình trong Magento_Ui/js/core/appmô-đun sẽ kiểm tra componentskhóa của đối tượng được truyền và đối với từng đối tượng phụ sẽ

  1. Tìm nạp đối tượng được trả về bởi RequireJSmô-đun đã chỉ định từ componentkhóa ( Magento_Customer/js/view/customer)

  2. Sử dụng đối tượng đó để khởi tạo một đối tượng javascript mới (xem bên dưới)

  3. Chỉ định bất kỳ khóa dữ liệu bổ sung cho cùng một đối tượng

  4. Thêm cùng một đối tượng vào uiRegistryvới khóa của đối tượng ban đầu ( customerở trên)

Nếu bạn không chắc x-magento-initkịch bản hoạt động như thế nào , tôi đã viết một bài viết về nó ở đây .

Có một bài kiểm tra chuyên sâu hơn về app.jsquá trình trong câu trả lời này .

Việc thực hiện ràng buộc phạm vi được xác định ở đây

vendor/magento//module-ui/view/base/web/js/lib/ko/bind/scope.js

Alan đó là một câu trả lời tuyệt vời! Cảm ơn bạn đã thông tin. Về điểm đạn 3, nó sẽ thêm các khóa dữ liệu bổ sung cho đối tượng vừa được tạo như thế nào. Nó sẽ là tài sản hay cái gì khác?
Timik
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.