Magento 2는 녹아웃 JS 바인딩을 어떻게 적용합니까?


19

KnockoutJS 문서를 매우 꼼꼼하게 읽으면 매우 기본적인 Knockout 뷰를 초기화하는 것은 다음과 같습니다.

// 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());

즉, 객체 생성자로 사용되는 자바 스크립트 함수를 생성하고 객체를 인스턴스화 한 다음 해당 객체를 ko.applyBindings전역 녹아웃 객체 ( ko) 의 메소드에 전달합니다.

그러나 Magento 2에서 Grid UI와 함께 백엔드 페이지를로드하면 Magento는 js/core/app.jsRequireJS 모듈을 초기화합니다.

/**
 * 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);
    };
});

이 모듈은 Magento의 KnockoutJS 사용을 초기화 Magento_Ui/js/lib/ko/initialize하는 것으로 보이는 모듈을 로드합니다 . 그러나 초기화 모듈의 소스를 보면.

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();
});

Magento가 view object없이ko.applyBindings(); 객체 라고 합니다 . 이것은 말이되지 않으며 Knockout 또는 Magento에 대한 제한된 이해가 여기에서 사용자 정의 / 이상한 일을하는지 확실하지 않습니다.

Magento가 실제로 녹아웃 바인딩을 적용하는 곳입니까? 아니면 다른 곳에서 발생합니까? 아니면 Magento가 Knockout 코드를 가로 채어 다른 곳에서 처리하기 까다로운 작업을 수행하고 있습니까?

답변:


38

Magento_Ui/js/lib/ko/initialize라이브러리는 실제로 Magento가 녹아웃 인스턴스를 초기화합니다. Magento 바인딩을 적용 할 때 ViewModel을 할당 하지 않습니다 .

여기에 누락 된 키입니다 바인딩 사용자 정의 KnockoutJS 이름 scope.

Magento의 Knockout 인스턴스가 scope:이와 같은 바인딩을 만나면

<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>

이 바인딩의 값 ()을 가져 와서 customer이를 사용하여 내부 노드에 대한 ViewModel을로드하고 적용합니다 uiRegistry. 간단한 KnockoutJS pre디버깅으로 특정 범위에 바인딩 된 데이터를 디버깅 할 수 있습니다.

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

uiRegistry구현 객체 같은 간단한 사전이다 Magento_Ui/js/lib/registry/registryRequireJS 모듈.

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

객체는 다음과 같은 자바 스크립트 비트를 통해 레지스트리에 저장됩니다.

<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>

Magento_Ui/js/core/app모듈 의 프로그램 components은 전달 된 객체 의 키를 검사하고 각 하위 객체는

  1. 지정된 RequireJS모듈이 반환 한 객체를 component키 에서 가져옵니다 ( Magento_Customer/js/view/customer)

  2. 해당 객체를 사용하여 자바 스크립트 객체를 인스턴스화 합니다 (아래 참조).

  3. 동일한 객체에 추가 데이터 키를 할당하십시오.

  4. uiRegistry원래 객체의 키 를 사용하여 동일한 객체를에 추가하십시오 ( customer위).

x-magento-init스크립트의 작동 방식을 잘 모르는 경우 여기에 대한 기사를 작성했습니다 .

이 답변에서app.js 프로세스 에 대한 심층적 인 검토가 있습니다.

범위 바인딩의 구현은 여기에 정의되어 있습니다

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

Alan 훌륭한 답변입니다! 정보 주셔서 감사합니다. 글 머리 기호 3과 관련하여 새로 인스턴스화 된 객체에 추가 데이터 키를 추가하는 방법은 무엇입니까? 속성이나 다른 것입니까?
Timik
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.