{"id":230882,"date":"2022-12-07T11:56:00","date_gmt":"2022-12-07T08:56:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=230882"},"modified":"2022-12-07T11:49:06","modified_gmt":"2022-12-07T08:49:06","slug":"kulmatapahtumien-kaeynnistaeminen-jquerylla","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/fi\/kulmatapahtumien-kaeynnistaeminen-jquerylla\/","title":{"rendered":"Kulmatapahtumien k\u00e4ynnist\u00e4minen jQuerylla"},"content":{"rendered":"\n<p>Yksi asioista, joista nautin WordPressin kanssa ty\u00f6skentelyss\u00e4, on kyky tuoda kolmannen osapuolen kirjastoja ja ty\u00f6kaluja ty\u00f6skentelyyn.<\/p>\n<p>T\u00e4m\u00e4 ei tarkoita, etteiv\u00e4tk\u00f6 he tulisi ilman oppimisk\u00e4yr\u00e4\u00e4n (he kaikki tekev\u00e4t, eik\u00f6 niin?), mutta on usein hauskaa \u2013 vaikkakin toisinaan turhauttavaa \u2013 sis\u00e4llytt\u00e4\u00e4 ja sitten manipuloida sit\u00e4, mit\u00e4 olet tekem\u00e4ss\u00e4.<\/p>\n<p>Mit\u00e4 tulee kolmannen osapuolen teknologioihin, olen n\u00e4hnyt ihmisten tuovan mukanaan esimerkiksi <strong><a href=\"https:\/\/packagist.org\/packages\/withfatpanda\/illuminate-wordpress\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Laravel Illuminate -paketin<\/a><\/strong> WordPressin kanssa.<\/p>\n<p><a href=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-162460-61e73f54b1a2e.png\" data-rel=\"lightbox\"><img decoding=\"async\" class=\"SDStudio-light-box-enable SDStudio-editor-tools-md-imp\" src=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-162460-61e73f54b1a2e.png\" alt=\"Kulmatapahtumien k\u00e4ynnist\u00e4minen jQuerylla\" ><\/a><\/p>\n<p>Ja tied\u00e4n, ett\u00e4 varsinkin viime vuosina monet ovat tuoneet komponentteja, kuten <strong><a href=\"https:\/\/reactjs.org\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">React<\/a><\/strong> ja <strong><a href=\"https:\/\/vuejs.org\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Vue<\/a><\/strong>.<\/p>\n<p><a href=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-162460-61e73f5876c07.png\" data-rel=\"lightbox\"><img decoding=\"async\" class=\"SDStudio-light-box-enable SDStudio-editor-tools-md-imp\" src=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-162460-61e73f5876c07.png\" alt=\"Kulmatapahtumien k\u00e4ynnist\u00e4minen jQuerylla\" ><\/a><\/p>\n<p>Yhdess\u00e4 t\u00e4llaisessa tapauksessa olen ty\u00f6skennellyt <strong><a href=\"https:\/\/angular.io\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Angularin<\/a><\/strong> kanssa. Ja jos olet tottunut ES6:een, vanilja JavaScriptiin tai jQueryyn, Angular-tapahtumien k\u00e4ynnist\u00e4minen jQuerylla voi aluksi tuntua hieman oudolta.<\/p>\n<p><a href=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-162460-61e73f5cad032.png\" data-rel=\"lightbox\"><img decoding=\"async\" class=\"SDStudio-light-box-enable SDStudio-editor-tools-md-imp\" src=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-162460-61e73f5cad032.png\" alt=\"Kulmatapahtumien k\u00e4ynnist\u00e4minen jQuerylla\" ><\/a><\/p>\n<p>Mutta kun ymm\u00e4rr\u00e4t merkinn\u00e4n ja kuinka Angular k\u00e4sittelee tapahtumiaan, se ei ole niin paha.<\/p>\n<h2>Kulmatapahtumien k\u00e4ynnist\u00e4minen jQuerylla<\/h2>\n<p>Angular toimii hieman eri tavalla kuin jQuery siin\u00e4, miten se on vuorovaikutuksessa DOM:n kanssa aina, kun tapahtuma tapahtuu.<\/p>\n<p>Oletetaan esimerkiksi, ett\u00e4 k\u00e4ytt\u00e4m\u00e4ll\u00e4 jQuery\u00e4 (tai jopa vanilja JavaScripti\u00e4) meill\u00e4 on sivu ja sitten sill\u00e4 sivulla on joukko merkint\u00f6j\u00e4, jotka voivat sis\u00e4lt\u00e4\u00e4 erilaisia \u200b\u200belementtej\u00e4. N\u00e4m\u00e4 voivat olla:<\/p>\n<ul>\n<li>otsikot,<\/li>\n<li>kappaleet,<\/li>\n<li>etiketit,<\/li>\n<li>valita elementtej\u00e4,<\/li>\n<li>ja niin edelleen.<\/li>\n<\/ul>\n<p>jQueryn kanssa olemme tottuneet tekem\u00e4\u00e4n jotain t\u00e4llaista:<\/p>\n<ol>\n<li>etsi elementti, jota haluamme k\u00e4ytt\u00e4\u00e4 joko tunnuksen, luokan nimen tai muun m\u00e4\u00e4ritteen avulla,<\/li>\n<li>kuuntele tapahtumaa,<\/li>\n<li>vastata asianmukaisesti.<\/li>\n<\/ol>\n<p>Joidenkin jQueryn uudempien ominaisuuksien ansiosta pystymme m\u00e4\u00e4rittelem\u00e4\u00e4n mukautettuja tapahtumia ja sitten asettamaan kuuntelijoita ja k\u00e4sittelem\u00e4\u00e4n niit\u00e4 asianmukaisesti, mutta yleinen toimintatapa on edelleen sama.<\/p>\n<p>Angular toimii kuitenkin hieman eri tavalla.<\/p>\n<p>Yksinkertaisuuden vuoksi (koska muistan, ett\u00e4 yrit\u00e4n vain k\u00e4yd\u00e4 l\u00e4pi Angular-tapahtumien k\u00e4ynnist\u00e4misprosessin jQuerylla), Angularissa on merkint\u00e4 aivan kuten miss\u00e4 tahansa tavallisessa HTML-asiakirjassa poikkeuksella.<\/p>\n<p>Nimitt\u00e4in mit\u00e4 tahansa kulmapohjaista merkint\u00e4\u00e4 ohjaavat mukautetut attribuutit, joiden etuliitteen\u00e4 on <strong>ng.<\/strong> N\u00e4m\u00e4 k\u00e4skev\u00e4t Angularia kuuntelemaan tiettyj\u00e4 tapahtumia, kun ne tapahtuvat, ja ryhtym\u00e4\u00e4n toimiin, kun ne tapahtuvat.<\/p>\n<p>Jos esimerkiksi elementiss\u00e4 on attribuutti, joka n\u00e4ytt\u00e4\u00e4 <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/3444d2be3556fc0c67036d5e3b2a6390#file-angular-markup-example-html\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">t\u00e4lt\u00e4<\/a><\/strong> :<\/p>\n<pre><code>&lt;select class=\"form-control ng-pristine ng-untouched ng-valid ng-empty\" ng-model=\"item.payment_method\" ng-change=\"updatePaymentMethod(item)\" ng-options=\"method.display_name for method in paymentMethods track by method.id\"&gt;\n  &lt;!-- more to come --&gt;\n&lt;\/select&gt;<\/code><\/pre>\n<p>Sitten se tarkoittaa, ett\u00e4 aina kun <strong>muutostapahtuma<\/strong> k\u00e4ynnistyy, Angularin on k\u00e4ynnistett\u00e4v\u00e4 asianmukainen k\u00e4sittelij\u00e4 ja teht\u00e4v\u00e4 kaikki tarvittava varmistaakseen, ett\u00e4 tietoja k\u00e4sitell\u00e4\u00e4n oikein.<\/p>\n<p>Mutta t\u00e4ss\u00e4 on alkuper\u00e4inen kysymys: Kuinka voimme laukaista Angular-tapahtumia jQuerylla?<\/p>\n<h3>Pient\u00e4 asettelua<\/h3>\n<p>Ennen kuin aloitan t\u00e4m\u00e4n tekemisen, haluan luoda <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/3444d2be3556fc0c67036d5e3b2a6390#file-angular-markup-html\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">esimerkkikoodin<\/a><\/strong>, joka perustuu Angulariin, joten olemme samalla sivulla sen suhteen, mist\u00e4 puhun:<\/p>\n<pre><code>&lt;select class=\"form-control ng-pristine ng-untouched ng-valid ng-empty\" ng-model=\"item.payment_method\" ng-change=\"updatePaymentMethod(item)\" ng-options=\"method.display_name for method in paymentMethods track by method.id\"&gt;\n  &lt;option value=\"?\"&gt;&lt;\/option&gt;\n  &lt;option value=\"1042\" selected=\"selected\"&gt;Card 1001 (01\/18)&lt;\/option&gt;\n&lt;\/select&gt;<\/code><\/pre>\n<p>Lyhyesti sanottuna t\u00e4m\u00e4 on valittu elementti, jossa on useita vaihtoehtoja. Tavoitteena on kaksijakoinen:<\/p>\n<ol>\n<li>muuttaa arvoa ohjelmallisesti jQueryn avulla,<\/li>\n<li>l\u00e4hett\u00e4\u00e4 tiedot k\u00e4ytt\u00e4m\u00e4ll\u00e4 alkuper\u00e4isi\u00e4 Angular-funktioita.<\/li>\n<\/ol>\n<p>Tarpeeksi suoraviivaista, eik\u00f6? Toki, mutta on muutamia huomionarvoisia asioita, ja k\u00e4sittelen niit\u00e4 seuraavassa osiossa.<\/p>\n<h3>Nyt jQueryyn<\/h3>\n<p>Oletetaan nyt, ett\u00e4 aiomme tehd\u00e4 jotain <strong>valituilla<\/strong> elementeill\u00e4, mutta emme aio k\u00e4ytt\u00e4\u00e4 Angularia. Sen sijaan aiomme k\u00e4ytt\u00e4\u00e4 jQuery\u00e4.<\/p>\n<p>Mutta koska ratkaisu on rakennettu, Angular odottaa <strong>muutostapahtuman<\/strong> laukaisua DOM:ssa, jotta kehys voi tehd\u00e4 teht\u00e4v\u00e4ns\u00e4. Mutta jQuery toimii eri tavalla, eik\u00f6 niin? Sen sijaan se ottaa tapahtuman, k\u00e4ytt\u00e4\u00e4 m\u00e4\u00e4ritt\u00e4m\u00e4\u00e4mme tilaajaa ja k\u00e4sittelee sen sitten.<\/p>\n<p>T\u00e4ss\u00e4 kohtaa ty\u00f6mme Angular-tapahtumien k\u00e4ynnist\u00e4misess\u00e4 jQueryn avulla tulee esiin. Selvyyden vuoksi se ei ole niin yksinkertaista kuin koodin soittaminen jQueryn kautta <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/3444d2be3556fc0c67036d5e3b2a6390#file-jquery-change-event-js\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">seuraavasti<\/a><\/strong> :<\/p>\n<pre><code>$('select['ng-model=\"item.payment_method\"]').trigger('change');<\/code><\/pre>\n<p>Sen sijaan voimme asettaa arvon jQuerylla, mutta sitten meid\u00e4n on k\u00e4ytett\u00e4v\u00e4 Angular-toimintoa oikean tapahtumak\u00e4sittelij\u00e4n k\u00e4ynnist\u00e4miseksi. Se on edelleen <strong>muutostapahtuma<\/strong>, mutta miten teemme sen, on eri asia.<\/p>\n<p><strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/3444d2be3556fc0c67036d5e3b2a6390#file-angular-change-event-js\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Seuraavassa koodissa<\/a><\/strong> n\u00e4et, miss\u00e4 muutan Select-elementti\u00e4 ja asetan sen toisen vaihtoehdon valituksi vaihtoehdoksi ja k\u00e4skee sitten Angularia tekem\u00e4\u00e4n asiansa k\u00e4ynnist\u00e4m\u00e4ll\u00e4 <strong>muutostapahtuman<\/strong>, johon elementti on sidottu.<\/p>\n<pre><code>$('select[ng-model=\"schedule.payment_method\"]').each(function() {\n\n  \/\/ For the purposes of this example, we're going to select the first option.\n  $(this)\n    .children('option:eq(1)')\n    .attr('selected', 'selected');\n\n  \/\/ Make sure the select element reflects the change (as setting the option doesn't always do this properly).\n  $(this).val($(this).children('option:selected').attr('value'));\n\n  \/\/ Now use the Angular API's triggerHandler function to call the change.\n  angular.element($(this)).triggerHandler('change');\n});<\/code><\/pre>\n<p>Kuten n\u00e4ette, ei ole juurikaan eroa; Sen sijaan, ett\u00e4 kutsuisimme\u00a0 elementin <a href=\"https:\/\/api.jquery.com\/trigger\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">liipaisinta<\/a> jQueryn kautta, k\u00e4yt\u00e4mme Angularin tarjoamaa API:ta. Ja se hoitaa sen.<\/p>\n<h2>T\u00e4llaisia \u200b\u200btekniikoita harkiten<\/h2>\n<p>En ole Angular-asiantuntija (enk\u00e4 ole v\u00e4itt\u00e4nytk\u00e4\u00e4n olevani), mutta kun tulee ty\u00f6skentelem\u00e4\u00e4n voimakkaasti muokatun, kolmannen osapuolen ratkaisun ja k\u00e4ytett\u00e4viss\u00e4ni olevien ty\u00f6kalujen sek\u00e4 aika- ja budjettirajoitusten kanssa, se on hy\u00f6dyllist\u00e4. tiet\u00e4\u00e4 kuinka k\u00e4sitell\u00e4 n\u00e4it\u00e4 asioita.<\/p>\n<p>Joten ehk\u00e4 t\u00e4st\u00e4 on sinulle apua tulevassa projektissa.<\/p>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/tommcfarlin.com\" class=\"external external_icon\">tommcfarlin.com<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Olen tehnyt t\u00f6it\u00e4 Angularin kanssa. Ja jos olet tottunut ES6:een, vanilja JavaScriptiin tai jQueryyn, Angular-tapahtumien k\u00e4ynnist\u00e4minen jQuerylla voi aluksi tuntua hieman oudolta.<\/p>\n","protected":false},"author":1,"featured_media":236442,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[730,719,895],"tags":[1166],"class_list":["post-230882","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-javascript-5","category-kehittaejae","category-koodi","tag-affiai-fi"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/posts\/230882","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/comments?post=230882"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/posts\/230882\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/media\/236442"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/media?parent=230882"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/categories?post=230882"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/tags?post=230882"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}