Knockout JS Magento 2 içerisinde nasıl kullanılır?


12

Benim sorunum:

Magento 2 içinde küçük bir Knockout JS uygulaması yazmaya çalışıyorum, ben ko.applyBindings(AppViewModel, document.getElementById("koTest"));Magento tarafından kullanılan Nakavt'ı kırar ve bu hatayı atar gibi uygulamayı başlatmak için mücadele ediyorum :

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

Şüpheli:

Bunun Magento 2'nin zaten ko.applyBindings()içinde kullandığından şüpheleniyorum app/code/Magento/Ui/view/base/web/js/lib/knockout/bootstrap.js. Ve bu bir düğümü belirtmediği için ko.applyBindingstekrar kullanamıyorum .

Kodumda kullanmazsam ko.applyBindings(AppViewModel, document.getElementById("koTest"))uygulamam başlamaz.

Bu beni bir şekilde ko.applyBindings()knockout / bootstrap.js kullanmam gerektiğini düşündürüyor ama nasıl bir fikrim yok, kimse yardımcı olabilir mi? Nakavt ile ilgili çok az deneyimim var.

Kodum

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

Yanıtlar:


23

Html şablonları kullanmanız gerekmeyen basit yöntem

Vinai Kopp sayesinde nihayet buna bir cevap aldım, önceki hacky geçici çözümümden çok daha basit (düğümleri temizliyordum). Tek yapmanız gereken 'ko'bir bağımlılık olarak tanımlamak ve kodunuzu bir döndürme işlevi içine eklemektir.

Aşağıda, JSON aracılığıyla iletilen bazı metinleri gösteren basit bir örnek verilmiştir.

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

Burada Magento'ya bileşenlerimizin kapsamını söylüyoruz (bu, data-bind: "scope: 'example-scope'"herhangi bir ek veriyle eşleşmeli ve geçmelidir. Bu temel URL, basit bir mesaj, hemen hemen istediğiniz her şey olabilir. Örnek olarak bir dize (PHP echo) geçtim.

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

Ve burada Javascript'imizi yazıyoruz.

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

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

 Sonuç

resim açıklamasını buraya girin

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

HTML şablonlarını kullanmanız gereken yöntem

Magento2 / Knockout içinde HTML şablonlama sistemini kullanmak istiyorsanız (ki önemli işleriniz için ihtiyacınız olacağını varsayalım) basitleştirilmiş cevabımla (aşağıda) karşılaştırıldığında yapmanız gereken birkaç değişiklik var.

Şablon işlevselliğine ihtiyacınız yoksa eski basitleştirilmiş cevabımın üzerine gidin.

Bu örnek için kullandığım dosyalar:

  • 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 şablon dosyası

PHTML şablonumuzdaki tek değişiklik, getTemplate()işleve yapılan çağrıdır :

<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 (bileşen) dosyası

JS dosyasında yapmanız gereken birkaç değişiklik var, bunları aşağıda detaylandıracağım.

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 - Dönüş işlevinizin artık uiComponent modülünü genişletmesi gerekiyor:

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

2 - Bir initializeişlev ve çağrı eklemeniz gerekir this._super(). this._super()üst bileşenin işlevini aynı adla çağırır. Bu durumda Yani düşünüyorum çağıracağı initializearasında uiComponent.

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

3 - İsteğe bağlı - Bileşeniniz için bazı varsayılanlar da burada ayarlayabilirsiniz, bence bu, bileşeninizin çalışmasını kolaylaştırdığı için takip edilmesi iyi bir uygulamadır. Yeniden kullandığınızda, varsayılanları koruyabilir veya özelleştirmek isterseniz, bileşeni değiştirmeden yeni bağımsız değişkenlerle çağırabilirsiniz.

Eğer JS varsayılan bakarsak Örneğin, setleri exampleMessageiçin 'Hello?'henüz sayfa olarak metin oluşturma edilir Hello Magento Stack Exchange!. Bunun nedeni exampleMessage, bileşeni çağırdığımda PHTML dosyasında üzerine yazdım.

HTML şablonu

Hala kazmak ve HTML şablonlarının neler yapabileceğini görmek için, Knockout JS belgelerinde belirtilen özelliklerin burada oldukça esnek hale getirilmesinde kullanılabileceğini düşünüyorum.

Şimdilik bazı lorem ipsum metni ekledim, HTML şablonlarının neler yapabileceğini anladıktan sonra muhtemelen başka bir soru / cevap vereceğim.

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!

Sonuç ve varsayılanların üzerine yazma

Daha önce de belirtildiği exampleMessagegibi, şablonun üzerine yazdığımı görebildiğiniz gibi, metin okurken çalıştığını görebilirsiniz Hello Magento Stack Exchange.

resim açıklamasını buraya girin

Şablon dosyasında geçersiz kılmayı kaldırırsam exampleMessagevarsayılan değerine dönecektir Hello?. Ben silmeniz gerekir yoktu var/view_preprocessedve pub/static/frontendbu olsa değiştirdikten sonra. Magento'nun değeri önbelleğe aldığını düşünüyorum.

resim açıklamasını buraya girin


Bu Magento2.1
Venkat

@Venkat - Yani düğümü temizlemeye gerek kalmadan Knockout'u kolayca kullanabileceğiniz anlamına mı geliyor? Ya da benim düzeltmem 2.1'de çalışıyor mu?
Ben Crook

Düzeltmeniz 2.1'de mi çalışacak?
Venkat

Benim için bağlamalar çalıştı ama ilk giriş veri bağlama için referans hatası alıyorum
Venkat

Bence KnockoutJS 2.0.X'ten beri çok fazla değişmemiş gibi görünüyor - 2.1'de denemedim ama% 100 emin değilim. Ayrıca, bunun en iyi yöntem olup olmadığından emin olmadığım için bazı kapsamlı testler yaptığınızdan emin olun, ancak bulabildiğim tek kişi bu.
Ben Crook

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.