Magento 2에서 녹아웃 JS를 사용하는 방법


12

내 문제:

Magento 2 내에서 작은 녹아웃 JS 앱을 작성하려고 시도 중입니다. 앱을 사용할 때 ko.applyBindings(AppViewModel, document.getElementById("koTest"));Magento에서 사용하는 녹아웃을 중단 하고이 오류가 발생하는 것처럼 앱을 초기화하는 데 어려움을 겪고 있습니다 .

Uncaught Error: You cannot apply bindings multiple times to the same element.

나는 그것이 다음과 같은 이유로 의심합니다.

나는 이것이 Magento 2가 이미 ko.applyBindings()within을 사용했기 때문이라고 생각합니다 app/code/Magento/Ui/view/base/web/js/lib/knockout/bootstrap.js. 그리고 그것은 노드를 지정하지 않기 때문에 ko.applyBindings다시 사용할 수 없습니다 .

ko.applyBindings(AppViewModel, document.getElementById("koTest"))내 코드에서 사용 하지 않으면 앱이 초기화되지 않습니다.

이로 인해 어떻게 든 ko.applyBindings()knockout / bootstrap.js를 사용해야한다고 생각 하지만 어떻게 도울 수 있을지 모르겠습니다. 녹아웃에 대한 경험이 거의 없습니다.

내 코드

<script type="text/javascript">
    require([
        'ko'
    ], function(ko) {
        // This is a simple *viewmodel* - JavaScript that defines the data and behavior of your UI
        function AppViewModel() {

            this.firstName = ko.observable("Bert");
            this.lastName = ko.observable("Bertington");
            this.fullName = ko.computed(function() {
                return this.firstName() + " " + this.lastName();
            }, this);

            this.capitalizeLastName = function() {
                var currentVal = this.lastName();
                this.lastName(currentVal.toUpperCase());
            };
        }

        ko.applyBindings(AppViewModel, document.getElementById("koTest"));
    });
</script>

<!-- This is a *view* - HTML markup that defines the appearance of your UI -->

<div id="koTest">
    <p>First name: <strong data-bind="text: firstName"></strong></p>
    <p>Last name: <strong data-bind="text: lastName"></strong></p>
    <p>Full name: <strong data-bind="text: fullName"></strong></p>

    <p>First name: <input data-bind="value: firstName" /></p>
    <p>Last name: <input data-bind="value: lastName" /></p>
    <p>Full name: <input data-bind="value: fullName" /></p>

    <button data-bind="click: capitalizeLastName">Capitalise</button>
</div>

1
여기에 튜토리얼이 있습니다 : inchoo.net/magento-2/knockout-js-in-magento-2
Aaron Allen

답변:


23

HTML 템플릿을 사용할 필요가없는 간단한 방법

Vinai Kopp 덕분에 마침내 이것에 대한 답변을 얻었습니다. 이전의 해키 해결 방법 (노드를 청소하고있었습니다)보다 훨씬 간단합니다. 'ko'의존성으로 정의 하고 리턴 함수 안에 코드를 추가하기 만하면됩니다.

아래는 JSON을 통해 전달 된 일부 텍스트를 렌더링하는 간단한 예입니다.

app/code/VENODR/MODULE/view/frontend/templates/knockout-example.phtml

여기서 우리는 Magento에게 컴포넌트의 범위를 알려줍니다 (이것은 data-bind: "scope: 'example-scope'"추가 데이터와 일치 하고 전달 해야합니다 . 이것은 기본 URL, 간단한 메시지, 원하는 거의 모든 것이 될 수 있습니다. 예를 들어 문자열 (PHP echo)을 전달했습니다.

<script type="text/x-magento-init">
{
    "*": {
        "Magento_Ui/js/core/app": {
            "components": {
                "example-scope": {
                    "component": "VENDOR_MODULE/js/knockout-example",
                    "exampleMessage": "<?= __('Hello Magento Stack Exchange!') ?>"
                }
            }
        }
    }
}
</script>

<div data-bind="scope: 'example-scope'">
    <h2 data-bind="text: message"></h2>
</div>

그리고 여기에 자바 스크립트를 작성합니다.

app/code/VENDOR/MODULE/view/frontend/web/js/knockout-example.js

define(['ko'], function(ko) {
    return function(config) {
        this.message = ko.observable(config.exampleMessage);
    }
});

 결과

여기에 이미지 설명을 입력하십시오

---------------------

HTML 템플릿을 사용해야하는 방법

Magento2 / Knockout 내에서 HTML 템플릿 시스템을 사용하려면 (중요한 작업이 필요할 것으로 예상됩니다) 간단한 답변과 비교하여 몇 가지 변경 사항이 필요합니다 (아래).

템플릿 기능이 필요하지 않으면 이전의 간단한 답변으로 스크롤하십시오.

이 예제에 사용중인 파일은 다음과 같습니다.

  • app/design/frontend/VENDOR/THEME/Magento_Cms/templates/knockout.phtml
  • app/design/frontend/VENDOR/THEME/Magento_Cms/web/js/knockout-example.js
  • app/design/frontend/VENDOR/THEME/Magento_Cms/web/template/test.html

PHTML 템플릿 파일

PHTML 템플릿의 유일한 변경 사항은 getTemplate()함수 호출입니다 .

<script type="text/x-magento-init">
{
    "*": {
        "Magento_Ui/js/core/app": {
            "components": {
                "example-scope": {
                    "component": "Magento_Cms/js/knockout-example",
                    "exampleMessage": "<?= __('Hello Magento Stack Exchange!') ?>"
                }
            }
        }
    }
}
</script>

<div data-bind="scope: 'example-scope'">
    <h2 data-bind="text: message"></h2>
    <!-- ko template: getTemplate() --><!-- /ko -->
</div>

JS (컴포넌트) 파일

JS 파일을 변경해야 할 몇 가지 사항이 있습니다. 아래에 자세히 설명하겠습니다.

define(['ko', 'uiComponent'], function(ko, Component) {
    'use strict';

    return Component.extend({
        defaults: {
            exampleMessage: 'Hello?',
            template: 'Magento_Cms/test'
        },

        initialize: function() {
            this._super();
            console.log(this.exampleMessage);
            this.message = ko.observable(this.exampleMessage);
        }
    });
});

1-리턴 함수가 이제 uiComponent 모듈을 확장해야합니다.

return Component.extend({
    ...
});

2- initialize함수 를 추가 하고 호출 해야합니다 this._super(). this._super()같은 이름으로 부모 컴포넌트의 함수를 호출합니다. 이 경우에 그래서 나는 생각 이 호출 initializeuiComponent.

initialize: function() {
    this._super();
    ...
}.

3- 옵션 -여기에서 구성 요소에 대한 일부 기본값을 설정할 수도 있습니다. 구성 요소를 쉽게 사용할 수 있기 때문에 따르는 것이 좋습니다. 재사용 할 때 기본값을 유지하거나 사용자 정의하려는 경우 구성 요소를 변경하지 않고 새 인수로 호출 할 수 있습니다.

당신은 JS에서 기본값으로 보면 예를 들어, 설정 exampleMessage'Hello?'아직 페이지는 텍스트를 렌더링한다 Hello Magento Stack Exchange!. exampleMessage구성 요소를 호출했을 때 PHTML 파일로 덮어 쓰기 때문 입니다.

HTML 템플릿

나는 아직도 HTML 템플릿이 무엇을 할 수 있는지 알아보고 Knockout JS 문서 에 언급 된 기능 을 여기에서 사용하여 매우 유연하게 만들 수 있다고 가정합니다 .

방금 iplorm 텍스트를 추가했습니다 .HTML 템플릿이 무엇을 할 수 있는지 알아 낸 후에 다른 질문 / 응답을 제공 할 것입니다.

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Asperiores assumenda beatae blanditiis culpa cupiditate doloremque, expedita ipsum iure magni minima modi molestiae nulla optio porro ratione reiciendis repellat soluta voluptatum!

결과 및 기본값 덮어 쓰기

앞에서 언급했듯이 exampleMessage템플릿 내에서 덮어 쓴 것을 알 수 있으므로 텍스트가 읽는 것처럼 작동하는 것을 볼 수 있습니다 Hello Magento Stack Exchange.

여기에 이미지 설명을 입력하십시오

템플릿 파일에서 재정의를 제거하면 exampleMessage기본값으로 돌아갑니다 Hello?. 나는 삭제할 필요가 않았다 var/view_preprocessedpub/static/frontend이 생각을 변경 한 후. Magento가 값을 캐시했다고 가정합니다.

여기에 이미지 설명을 입력하십시오


이것은 Magento2.1
Venkat

@ Venkat-이제 노드를 정리하지 않고도 Knockout을 쉽게 사용할 수 있습니까? 아니면 내 수정이 2.1에서 작동합니까?
벤 크룩

당신의 수정은 2.1에서 작동합니까?
Venkat

나를 위해 바인딩이 작동했지만 첫 번째 입력 데이터 바인딩에 대한 참조 오류가 발생했습니다
Venkat

KnockoutJS가 2.0.X 이후로 많이 바뀌지 않은 것처럼 생각합니다. 2.1에서 시도하지 않았으므로 100 % 확실하지 않습니다. 또한 이것이 최선의 방법인지 확실하지 않으므로 철저한 테스트를 수행해야합니다.이 방법은 내가 찾을 수있는 유일한 방법입니다.
벤 크룩

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.