Struggling With Complex Data-Binding in Your Web Apps?
Managing complex data-binding in modern web apps can be overwhelming. Our skilled Knockout.js developers provide efficient solutions with clear, dynamic two-way data binding, ensuring that your app’s UI and data are perfectly synchronized.
We specialize in building scalable, fast-loading applications that reduce complexity and improve performance, making your user experience seamless.
What is KnockoutJS and how is it relevant in Magento 2?
If you have just started to learn Magento or have already been doing for some time, there is a higher chance that you have not given a deeper thought about learning Knockout JS. But, it is vital to understand Knockout JS as its “data-binding” concept has been used pretty well in some crucial elements of Magento such as minicart and checkout.
So in this blog, we will be explaining about Knockout JS, and hopefully, when you reach the end of it, you’ll be making knockout apps in Magento. So sit back, relax, and let the journey begin.
Want to skip the basics and go directly to the main section? Click here
What is Knockout JS?
Knockout JS is a Javascript library which uses the MVVM pattern to bind data to certain DOM elements. Within Magento, we usually define a View-Model (which is a .js file) and a Template (which is a .html file), and the data in the template file is bound to the view-model, meaning whenever the data in the view-model changes, the template file changes too.
Why use data-binding?
Some of you might be asking “Well can’t we just use some library like jQuery to do the DOM parsing manually?“, And the answer is, of course, you can. You don’t even need jQuery. You can do all the DOM manipulations with core Javascript as well. But libraries like these are there to help us in writing standardized, maintainable, and beautiful code. Here’s a simple example, let’s say there’s a page where the number of visitors is being displayed on 3 separate sections of the page<div class="visitors"></div> <!-- Some other HTML --> <div class="visitors"></div> <!-- Some other HTML --> <div class="visitors"></div>
Now our Javascript would look something like this, which would fetch new visitor data every second<script type="text/javascript"> (function ($) { var visitors = 0; var fetchVisitorUrl = "..."; var fetchVisitors = function () { $.get(fetchVisitorUrl, function (data) { visitors = data.visitors; $('.visitors').html(visitors); setTimeout(fetchVisitors, 1000); }); }; fetchVisitors(); })(window.jQuery); </script>
See the $('.visitors').html(visitors);? That line is responsible for actually making the DOM manipulation. Without that, even when the new visitor data is fetched, it’ll not be visible on the page. Now suppose a new developer working on your project decided to implement a better way to fetch visitor data? Using sockets perhaps? Then he/she would also have to write $('.visitors').html(visitors);in his/her code. Hence the code becomes messy and redundant. Using data-binding, we change only the View-Model, and the View changes automatically.
Knockout JS and Magento 2
To make a knockout app in Magento 2, first we create a new module. Next in our template file, we write the following<?php /* @var Codilar\HelloWorld\Block\Hello $block */ ?> <div data-bind="scope: 'knockout-tutorial'"> <!-- ko template: getTemplate() --><!-- /ko --> </div> <script type="text/x-magento-init"> { "*": { "Magento_Ui/js/core/app": { "components": { "knockout-tutorial": { "component": "Codilar_HelloWorld/js/viewModel", "template" : "Codilar_HelloWorld/template" } } } } } </script>
This is basically initiating the Magento_Ui/js/core/appwidget with the components passed as options, using the text/x-magento-init tag. The data-bind="scope: 'knockout-tutorial'"says knockout to use the knockout-tutorialcomponent and template inside that DIV.
define([ 'uiComponent', 'ko' ], function(Component, ko) { return Component.extend({ clock: ko.observable(""), initialize: function () { this._super(); setInterval(this.reloadTime.bind(this), 1000); }, reloadTime: function () { /* Setting new time to our clock variable. DOM manipulation will happen automatically */ this.clock(Date()); }, getClock: function () { return this.clock; } }); });
The View-Models inside of a Magento 2 application, must return a Component.extendfunction call, where the Component is an object of the uiComponent, which were required here. Inside our Component.extend, we pass an object, which must contain an initialize function which will be the “constructor of our class”, so to speak.
<!-- My View-Model file is Codilar_HelloWorld/js/viewModel --> <h1 data-bind="text: getClock()"></h1>
Now if we hit the url http://mywebsite.com/helloworld/ we should see a clock which should change every second, even though we didn’t explicitly do any DOM manipulations.
That’s all about how Magento 2 uses the knockout JS bindings. Do let us know in the comment section below about what you want my next Magento tutorial blog to be about. Also, don’t forget to check our previous tutorials!
Click here to download a zip copy of the above-mentioned project
Watch the video to learn more about KnockoutJS in Magento 2 (Demo).
If you’re interested in learning more about Magento and its potential as a Progressive Web App, be sure to check out our comprehensive guide on Progressive Web Apps for 2023
Previous Tutorials
What are widgets in jQuery & how are they different from regular objects/functions?
How to create a “HELLO WORLD” module in Magento 2?
Giới lập trình front-end ngày nay đã khá quen thuộc với Angular JS và ReactJS. 2 framework do Google và Facebook phát triển và ngày càng trở nên phổ biến.
Tuy nhiên, hai nền tảng này cũng đang có sự cạnh tranh nhau rất quyết liệt khiến cho developer không biết nên lựa chọn nền tảng nào để phát triển ứng dụng cho mình.
Ngoài ra, AngularJS và Reacts đòi hỏi developer phải có kiến thức vững vàng về JavaScript như xử lý object, string, cũng như mô hình MVC để có thể tiếp cận và sử dụng thành thạo.
Bài viết này muốn giới thiệu một hướng đi khác, đơn giản hơn, dễ tiếp cận hơn trong lập trình front-end đó là Knockout
Knockout là gì?
Nói đến từ Knockout, chắc hẳn bạn sẽ nghĩ đến coding theo phong cách của một boxer, nhưng thực ra thì không phải thế.
Knockout JS là thư viên javascript giúp bạn tạo các ứng dụng linh hoạt và mượt mà (responsive display). Với Knockout, bạn có thể làm cho giao diện của ứng dụng được update tự động một cách đơn giản, dễ dàng khi có thay đổi data.
Vì sao nên sử dụng Knockout?
Knockout đem lại cho bạn rất nhiều sự tiện lợi
Knockout là một Pure Javascript library nên hoàn toàn tương thích với mọi trình duyệt
Dung lượng nhỏ, đơn giản nên không ảnh hưởng tới performance của trang web
Tài liệu hướng dẫn guideline khá đầy đủ, Knockout là một framework dễ học, dễ tiếp cận nhờ tính đơn giản của nó.
Tóm lại, Knockout là framework rất đáng để tìm hiểu.Kiến trúc và nguyên tắc hoạt động
Knockout được phát triển dựa trên mô hình Model-View-View Model (MVVM).
Trong mô hình này
Model: là phần chứa dữ liệu của ứng dụng và nó được tách riêng với phần giao diện người dùng (UI).
View: là phần giao diện người dùng như layout, GUI, những thứ hiển thị trên màn hình cho user sử dụng
View Model: là phần mô tả trạng thái của dữ liệu trên model, là trung gian giữa View và Model, quản lý phần dữ liệu mà người dùng đang tương tác. MVVM sử dụng cơ chế đặc biệt là Data Binding để cập nhật dữ liệu từ Model vào GUI component như TextBox, Button mà không cần sử dụng code-behind như thông thường.
Không phức tạp như Angular hay React, kiến trúc của Knockout rất đơn giản chỉ bao gồm 3 core feature
Observables là một Java objects của Knockout có tác dụng thông báo cho UI biết khi View Model thay đổi
Declarative Bindings: Hiểu đơn giản là Knockout gán value của một biến Javascript vào GUI ví dụ như textbox, button. Ví dụ:
Chú ý đoạn xử lý data-bind trong code trên, đây chính là xử lý databinding của Knockout. Cho phép cập nhật data vào GUI
Step 3, Tạo Model
Tạo ra một Data Model để chứa dữ liệu, trường working chứa dữ liệu để bind vào dropdown box, trường name dùng để bind vào label
Data Model ở đây thực chất là một JavaScript object
function WorkingModel() {
this.working = [
{ name: "OT"},
{ name: "ON" },
{ name: "Fire" }
];
this.chosenWorkStyle = ko.observable();
}
Chú ý xử lý ko.observable(). Đây là xử lý giúp Knockout biết được khi nào thì View Model thay đổi.
Step 4, Apply Data Binding
Gọi api applyBindings để để thực hiện
$(document).ready(function () {
ko.applyBindings(new WorkingModel());
});
Chú ý xử lý này chỉ hoạt động khi toàn bộ trang web được load xong.
Bây giờ run ứng dụng, mỗi khi bạn thay đổi value trong dropdown box, thì trường text tự động cập nhật, mà không cần phải code thêm xử lý event change như thông thường.
Lời kết
Có thể nói KnockoutJs là một framework tuy nhỏ mà lại có võ. Với KnockoutJS, developer có thể thực hiện các kỹ thuật cao cấp hơn như binding dữ liệu, cập nhật dữ liệu dựa vào thao tác người dùng, từ trường này tự động sang các trường liên quan, KO (Key Observing – quan sát sự thay đổi theo key).
Hãy sử dụng Knockout, và code theo cách của 1 boxer.
Why did the Magento team choose KnockoutJS instead of a more popular framework like React or Angular? In addition to having a larger developer pool, there are reports that these frameworks are also faster than KO. The team must have their reasons for going with KO, but it doesn't change the fact that Magento 2 is not only much more complex than Magento 1.x, but also requires developers to learn a whole new JS framework whose knowledge is likely not transferable outside of Magento development.
Sounds like those are questions for Magento, not me :)
I can't speak for the Magento team, but as I understand it the new Magento 2 project started, in ernest, two and half year ago. Statistics on the use of Knockout may have been different then. Also, it's important to remember that the best tools for a team are the tools a team already knows.
Unfortunately, if you're going to be doing front-end development for more than 18 months, with Magento or not, that probably means coming up to speed on a new framework or two in that time.
Thanks for the reply, Alan. I'm just ranting out loud to let out some steam ^^. Our team already wants to go back to Magento 1.14 since our next project has a super aggressive timeline (two months from BRD to launch) and it's much more productive for people to work with what they're most familiar with, even though the older version might not be as "modern" as version 2. I'm all for v2, but I feel the migration path could've been smoother. I guess there is no smooth path moving to another mountain altogether.
Hey there! If you’ve seen my tutorial on how to write a ToDo app with KnockoutJS, you may have noticed that I wrote it with ES5. Or not, you may not have known that there's a looming update to JavaScript. It's not entirely supported by all browsers, yet, but there are ways to utilize the new features and also be backwards compatible. Babel, for instance.
If you want to use ES6 with the Knockout app, there are a few other steps that I'll likely cover in another tutorial. But here's how you would write the app utilizing the new OOP features of JavaScript:
Yesterday I met a guy who spent the day evangelising Polymer as a very reasonable solution to write web apps. I've never met this guy before but we got into very interesting a discussion around an argument that can easily lead toward a framework-religion war.
My javascript background is:
jQuery > Backbone > KnowckoutJS > ReactJS
which can be translated to:
spagetti > fireback > two ways binding > functional rendering
It took time to appreciate the functional rendering concept around ReactJS (and the whole FP philosophy as well) so my first reaction to Polymer was: "whaaaat the heeeeck?"
But of course it was my first reaction to ReactJS too, and to Knockout, and to Backbone... only jQuery got me with a "woooow!!!"
It's a new framework, plenty of new words, different code organization. So I told myself: "Youd have to roll up my sleeves and digg into it!".
Documentation is good. I give them that. And material design is great. Actually I've started by journey in Polymer web component catalog. It's basically an NPM for Polymer stuff.
Polymer catalog provides all the material design components out of the box.
And that is good enough for me to see how Polymer can help me in speed up the prototyping of a web-ish application.
Btw, my first concern about Polymer is that it bounds to the DOM when libraries like ReactJS try to abstract from it. I normally by abstraction. But, again, I can also see how the catalog can speed up prototyping.
And for the next three weeks prototyping speed is all I need.