{"id":30364,"date":"2025-09-26T23:41:24","date_gmt":"2025-09-26T20:41:24","guid":{"rendered":"https:\/\/fatihsoysal.com\/blog\/?p=30364"},"modified":"2025-09-26T23:41:24","modified_gmt":"2025-09-26T20:41:24","slug":"angular-uygulamalarinizda-ng2-dragula-ile-surukle-ve-birak-ozelligi","status":"publish","type":"post","link":"https:\/\/fatihsoysal.com\/blog\/angular-uygulamalarinizda-ng2-dragula-ile-surukle-ve-birak-ozelligi\/","title":{"rendered":"Angular Uygulamalar\u0131n\u0131zda ng2-dragula ile S\u00fcr\u00fckle ve B\u0131rak \u00d6zelli\u011fi"},"content":{"rendered":"<p><body><\/p>\n<h2>Angular Uygulamalar\u0131n\u0131zda ng2-dragula ile S\u00fcr\u00fckle ve B\u0131rak \u00d6zelli\u011fi<\/h2>\n<p>Modern web uygulamalar\u0131nda kullan\u0131c\u0131 deneyimi (UX), ba\u015far\u0131n\u0131n anahtarlar\u0131ndan biridir. Kullan\u0131c\u0131lar\u0131n aray\u00fczle etkile\u015fimini kolayla\u015ft\u0131ran ve sezgisel hale getiren \u00f6zellikler, uygulaman\u0131n benimsenme oran\u0131n\u0131 art\u0131r\u0131r. Bu \u00f6zelliklerden biri de &#8220;s\u00fcr\u00fckle ve b\u0131rak&#8221; (Drag &#038; Drop) i\u015flevselli\u011fidir. Dosya y\u00fcklemelerinden, liste s\u0131ralamalar\u0131na, panolar aras\u0131 g\u00f6rev ta\u015f\u0131malardan, g\u00f6rsel d\u00fczenleyicilere kadar pek \u00e7ok senaryoda s\u00fcr\u00fckle ve b\u0131rak, kullan\u0131c\u0131lar\u0131n i\u015f ak\u0131\u015f\u0131n\u0131 \u00f6nemli \u00f6l\u00e7\u00fcde h\u0131zland\u0131r\u0131r.<\/p>\n<p>Angular gibi g\u00fc\u00e7l\u00fc bir \u00f6n y\u00fcz framework&#8217;\u00fc ile uygulama geli\u015ftirirken, s\u00fcr\u00fckle ve b\u0131rak gibi karma\u015f\u0131k g\u00f6r\u00fcnen \u00f6zellikleri entegre etmek i\u00e7in haz\u0131r ve g\u00fcvenilir \u00e7\u00f6z\u00fcmlere ihtiya\u00e7 duyar\u0131z. \u0130\u015fte tam bu noktada <code>ng2-dragula<\/code> devreye giriyor. <code>ng2-dragula<\/code>, pop\u00fcler Dragula k\u00fct\u00fcphanesini Angular ekosistemine ta\u015f\u0131yan, kullan\u0131m\u0131 kolay ve esnek bir \u00e7\u00f6z\u00fcmd\u00fcr. Bu makalede, <code>ng2-dragula<\/code>&#8216;n\u0131n ne oldu\u011funu, neden tercih edilmesi gerekti\u011fini, temel ve ileri d\u00fczey kullan\u0131mlar\u0131n\u0131, \u00f6zelle\u015ftirme se\u00e7eneklerini, ger\u00e7ek d\u00fcnya senaryolar\u0131n\u0131 ve en iyi uygulamalar\u0131n\u0131 detayl\u0131 bir \u015fekilde inceleyece\u011fiz.<\/p>\n<h2>Neden ng2-dragula?<\/h2>\n<p>Angular uygulamalar\u0131n\u0131za s\u00fcr\u00fckle ve b\u0131rak \u00f6zelli\u011fi eklemek i\u00e7in birden fazla yol vard\u0131r. Kendi \u00e7\u00f6z\u00fcm\u00fcn\u00fcz\u00fc s\u0131f\u0131rdan yazabilir, <code>@angular\/cdk\/drag-drop<\/code> gibi Angular&#8217;\u0131n resmi bile\u015fen k\u00fct\u00fcphanesini kullanabilir veya <code>ng2-dragula<\/code> gibi \u00fc\u00e7\u00fcnc\u00fc taraf k\u00fct\u00fcphanelere y\u00f6nelebilirsiniz. Peki, <code>ng2-dragula<\/code>&#8216;y\u0131 di\u011ferlerinden ay\u0131ran ve onu cazip k\u0131lan \u00f6zellikler nelerdir?<\/p>\n<p>\u00d6ncelikle, <code>ng2-dragula<\/code>, <code>Dragula<\/code> k\u00fct\u00fcphanesinin kan\u0131tlanm\u0131\u015f sa\u011flaml\u0131\u011f\u0131n\u0131 ve basitli\u011fini Angular d\u00fcnyas\u0131na ta\u015f\u0131r. <code>Dragula<\/code>, \u00f6zellikle listeler aras\u0131nda veya ayn\u0131 liste i\u00e7inde \u00f6\u011feleri s\u00fcr\u00fckleyip b\u0131rakma i\u015flemleri i\u00e7in tasarlanm\u0131\u015f, hafif ve ba\u011f\u0131ml\u0131l\u0131\u011f\u0131 az bir JavaScript k\u00fct\u00fcphanesidir. <code>ng2-dragula<\/code> bu temeli alarak, Angular&#8217;\u0131n mod\u00fcler yap\u0131s\u0131na ve bile\u015fen tabanl\u0131 mimarisine m\u00fckemmel bir \u015fekilde entegre olur.<\/p>\n<p><code>ng2-dragula<\/code>&#8216;n\u0131n temel avantajlar\u0131 \u015funlard\u0131r:<\/p>\n<p>*   <strong>Basitlik ve H\u0131z:<\/strong> Kurulumu ve kullan\u0131m\u0131 son derece kolayd\u0131r. Sadece birka\u00e7 sat\u0131r kod ile s\u00fcr\u00fckle ve b\u0131rak i\u015flevselli\u011fini uygulaman\u0131za dahil edebilirsiniz.<br \/>\n*   <strong>Esneklik:<\/strong> Tek bir kapsay\u0131c\u0131 i\u00e7inde s\u0131ralama, birden fazla kapsay\u0131c\u0131 aras\u0131nda \u00f6\u011fe ta\u015f\u0131ma veya belirli kurallara g\u00f6re s\u00fcr\u00fckleme\/b\u0131rakma i\u015flemlerini kontrol etme gibi \u00e7e\u015fitli senaryolar\u0131 destekler.<br \/>\n*   <strong>Olay Tabanl\u0131 Mimari:<\/strong> S\u00fcr\u00fckleme, b\u0131rakma, \u00f6\u011fe \u00fczerine gelme gibi \u00e7e\u015fitli olaylar\u0131 dinleyerek uygulaman\u0131z\u0131n davran\u0131\u015f\u0131n\u0131 \u00f6zelle\u015ftirebilirsiniz. Bu, karma\u015f\u0131k i\u015f mant\u0131klar\u0131n\u0131 entegre etmek i\u00e7in g\u00fc\u00e7l\u00fc bir mekanizma sunar.<br \/>\n*   <strong>G\u00f6rsel \u00d6zelle\u015ftirme:<\/strong> S\u00fcr\u00fcklenen \u00f6\u011felerin, b\u0131rakma b\u00f6lgelerinin ve ge\u00e7ici yer tutucular\u0131n g\u00f6r\u00fcn\u00fcm\u00fcn\u00fc CSS ile kolayca de\u011fi\u015ftirebilirsiniz.<br \/>\n*   <strong>Veri Odakl\u0131 Yakla\u015f\u0131m:<\/strong> <code>dragulaModel<\/code> direktifi sayesinde, s\u00fcr\u00fckle ve b\u0131rak i\u015flemleri do\u011frudan veri modelinizle senkronize olur. Bu, uygulaman\u0131z\u0131n durumunu y\u00f6netmeyi basitle\u015ftirir.<\/p>\n<p>Bu avantajlar, \u00f6zellikle h\u0131zl\u0131 prototipleme yaparken veya karma\u015f\u0131k olmayan ancak sa\u011flam bir s\u00fcr\u00fckle ve b\u0131rak \u00e7\u00f6z\u00fcm\u00fcne ihtiya\u00e7 duydu\u011funuzda <code>ng2-dragula<\/code>&#8216;y\u0131 ideal bir se\u00e7enek haline getirir.<\/p>\n<h2>ng2-dragula ile Ba\u015flang\u0131\u00e7<\/h2>\n<p>Angular uygulaman\u0131za <code>ng2-dragula<\/code>&#8216;y\u0131 entegre etmek olduk\u00e7a basit bir s\u00fcre\u00e7tir. \u0130\u015fte ad\u0131m ad\u0131m yapman\u0131z gerekenler:<\/p>\n<h3>\u00d6n Gereksinimler<\/h3>\n<p>Ba\u015flamadan \u00f6nce a\u015fa\u011f\u0131daki ara\u00e7lar\u0131n sisteminizde kurulu oldu\u011fundan emin olun:<\/p>\n<p>*   <strong>Node.js ve npm:<\/strong> Angular CLI i\u00e7in gereklidir.<br \/>\n*   <strong>Angular CLI:<\/strong> <code>npm install -g @angular\/cli<\/code> komutuyla kurabilirsiniz.<br \/>\n*   <strong>Temel Angular Bilgisi:<\/strong> Bile\u015fenler, mod\u00fcller, direktifler ve servisler hakk\u0131nda temel bilgiye sahip olman\u0131z \u00f6nerilir.<\/p>\n<h3>Yeni Bir Angular Projesi Olu\u015fturma<\/h3>\n<p>E\u011fer halihaz\u0131rda bir Angular projeniz yoksa, yeni bir proje olu\u015fturarak ba\u015flayabiliriz:<\/p>\n<pre><code class=\"language-bash\">ng new my-drag-drop-app --routing false --style scss\ncd my-drag-drop-app<\/code><\/pre>\n<p>Bu komut, <code>my-drag-drop-app<\/code> ad\u0131nda yeni bir Angular projesi olu\u015fturacak ve SCSS stil dosyalar\u0131n\u0131 kullanacak \u015fekilde yap\u0131land\u0131racakt\u0131r.<\/p>\n<h3>ng2-dragula Kurulumu<\/h3>\n<p>Projenizin dizinine ge\u00e7tikten sonra, <code>ng2-dragula<\/code> ve temel ba\u011f\u0131ml\u0131l\u0131\u011f\u0131 olan <code>dragula<\/code> k\u00fct\u00fcphanelerini npm arac\u0131l\u0131\u011f\u0131yla kurun:<\/p>\n<pre><code class=\"language-bash\">npm install ng2-dragula dragula --save<\/code><\/pre>\n<p>Bu komut, k\u00fct\u00fcphaneleri projenizin <code>node_modules<\/code> klas\u00f6r\u00fcne indirecek ve <code>package.json<\/code> dosyan\u0131za ba\u011f\u0131ml\u0131l\u0131k olarak ekleyecektir.<\/p>\n<h3>Mod\u00fcl\u00fc \u0130\u00e7eri Aktarma<\/h3>\n<p><code>ng2-dragula<\/code>&#8216;y\u0131 kullanabilmek i\u00e7in, uygulaman\u0131z\u0131n ana mod\u00fcl\u00fcne (<code>app.module.ts<\/code> veya ilgili feature mod\u00fcl\u00fcn\u00fcze) <code>DragulaModule<\/code>&#8216;\u00fc i\u00e7eri aktarman\u0131z gerekir:<\/p>\n<pre><code class=\"language-typescript\">\/\/ src\/app\/app.module.ts\nimport { NgModule } from '@angular\/core';\nimport { BrowserModule } from '@angular\/platform-browser';\nimport { DragulaModule } from 'ng2-dragula'; \/\/ ng2-dragula mod\u00fcl\u00fcn\u00fc import ediyoruz\n\nimport { AppComponent } from '.\/app.component';\n\n@NgModule({\n  declarations: [\n    AppComponent\n  ],\n  imports: [\n    BrowserModule,\n    DragulaModule.forRoot() \/\/ DragulaModule'\u00fc forRoot() ile import ediyoruz\n  ],\n  providers: [],\n  bootstrap: [AppComponent]\n})\nexport class AppModule { }<\/code><\/pre>\n<p><code>DragulaModule.forRoot()<\/code> metodunu kullanmak \u00f6nemlidir, \u00e7\u00fcnk\u00fc bu, <code>DragulaService<\/code>&#8216;in uygulama genelinde tek bir \u00f6rne\u011finin (singleton) sa\u011flanmas\u0131n\u0131 garanti eder. E\u011fer bir feature mod\u00fcl\u00fcnde kullanacaksan\u0131z, <code>DragulaModule<\/code>&#8216;\u00fc <code>forRoot()<\/code> olmadan import edebilirsiniz.<\/p>\n<h3>CSS Dosyalar\u0131n\u0131 \u0130\u00e7eri Aktarma<\/h3>\n<p><code>ng2-dragula<\/code>&#8216;n\u0131n varsay\u0131lan stilini kullanmak i\u00e7in, <code>dragula<\/code>&#8216;n\u0131n CSS dosyas\u0131n\u0131 uygulaman\u0131za dahil etmeniz gerekir. Bunu yapman\u0131n en yayg\u0131n yolu, <code>angular.json<\/code> dosyan\u0131zdaki <code>styles<\/code> dizisine eklemektir:<\/p>\n<pre><code class=\"language-json\">\/\/ angular.json\n\"styles\": [\n  \"src\/styles.scss\",\n  \"node_modules\/dragula\/dist\/dragula.min.css\" \/\/ Dragula CSS'ini buraya ekliyoruz\n],<\/code><\/pre>\n<p>Alternatif olarak, <code>src\/styles.scss<\/code> (veya <code>src\/styles.css<\/code>) dosyan\u0131za do\u011frudan import edebilirsiniz:<\/p>\n<pre><code class=\"language-scss\">\/<em> src\/styles.scss <\/em>\/\n@import 'dragula\/dist\/dragula.min.css';<\/code><\/pre>\n<p>Bu ad\u0131mlar\u0131 tamamlad\u0131ktan sonra, <code>ng2-dragula<\/code>&#8216;y\u0131 Angular uygulaman\u0131zda kullanmaya haz\u0131rs\u0131n\u0131z demektir.<\/p>\n<h2>Temel Kullan\u0131m: Tekli S\u00fcr\u00fckle ve B\u0131rak Kapsay\u0131c\u0131s\u0131<\/h2>\n<p><code>ng2-dragula<\/code> ile s\u00fcr\u00fckle ve b\u0131rak i\u015flevselli\u011fini uygulaman\u0131n en basit yolu, tek bir liste i\u00e7indeki \u00f6\u011feleri yeniden s\u0131ralamakt\u0131r.<\/p>\n<h3>HTML Yap\u0131s\u0131<\/h3>\n<p>Bir s\u00fcr\u00fckle ve b\u0131rak kapsay\u0131c\u0131s\u0131 olu\u015fturmak i\u00e7in, \u00f6\u011feleri i\u00e7erecek HTML elementine (<code>div<\/code>, <code>ul<\/code>, <code>ol<\/code> vb.) <code>[dragula]<\/code> direktifini eklemeniz yeterlidir. Ayr\u0131ca, <code>[(dragulaModel)]<\/code> direktifi ile veri modelinizi bu kapsay\u0131c\u0131ya ba\u011flayabilirsiniz.<\/p>\n<pre><code class=\"language-html\"><!-- src\/app\/app.component.html -->\n<div class=\"container\">\n  <h2>Yap\u0131lacaklar Listesi<\/h2>\n  <ul [dragula]=\"'my-bag'\" [(dragulaModel)]=\"tasks\" class=\"task-list\">\n    <li *ngFor=\"let task of tasks\" class=\"task-item\">\n      {{ task }}\n    <\/li>\n  <\/ul>\n<\/div><\/code><\/pre>\n<p>Burada:<br \/>\n*   <code>[dragula]=\"'my-bag'\"<\/code>: Bu direktif, <code>ul<\/code> elementini &#8220;my-bag&#8221; ad\u0131nda bir Dragula grubuna dahil eder. Ayn\u0131 gruptaki t\u00fcm kapsay\u0131c\u0131lar aras\u0131nda s\u00fcr\u00fckle ve b\u0131rak i\u015flemi yap\u0131labilir. Tek bir kapsay\u0131c\u0131 olsa bile bir grup ad\u0131 vermek iyi bir pratiktir.<br \/>\n*   <code>[(dragulaModel)]=\"tasks\"<\/code>: Bu direktif, <code>tasks<\/code> adl\u0131 dizi ile s\u00fcr\u00fckle ve b\u0131rak kapsay\u0131c\u0131s\u0131 aras\u0131ndaki iki y\u00f6nl\u00fc veri ba\u011flamay\u0131 sa\u011flar. \u00d6\u011felerin s\u0131ras\u0131 de\u011fi\u015fti\u011finde, <code>tasks<\/code> dizisi otomatik olarak g\u00fcncellenir.<br \/>\n<em>   <code><\/em>ngFor=\"let task of tasks\"<\/code>: Her bir g\u00f6revi listede g\u00f6sterir.<\/p>\n<h3>Bile\u015fen Mant\u0131\u011f\u0131<\/h3>\n<p>Bile\u015feninizde (<code>app.component.ts<\/code>), s\u00fcr\u00fckle ve b\u0131rak\u0131lacak \u00f6\u011feleri i\u00e7eren bir dizi tan\u0131mlaman\u0131z gerekir:<\/p>\n<pre><code class=\"language-typescript\">\/\/ src\/app\/app.component.ts\nimport { Component, OnInit } from '@angular\/core';\nimport { DragulaService } from 'ng2-dragula';\n\n@Component({\n  selector: 'app-root',\n  templateUrl: '.\/app.component.html',\n  styleUrls: ['.\/app.component.scss']\n})\nexport class AppComponent implements OnInit {\n  title = 'my-drag-drop-app';\n  tasks: string[] = ['G\u00fcne\u015flen', 'Kitap oku', 'Kod yaz', 'Yemek yap', 'Spor yap'];\n\n  constructor(private dragulaService: DragulaService) {\n    \/\/ S\u00fcr\u00fckle ve b\u0131rak olaylar\u0131n\u0131 dinlemek i\u00e7in \u00f6rnek bir kullan\u0131m\n    this.dragulaService.drag('my-bag').subscribe(({ el }) => {\n      console.log('\u00d6\u011fe s\u00fcr\u00fckleniyor:', el);\n    });\n\n    this.dragulaService.drop('my-bag').subscribe(({ el, target, source, sibling }) => {\n      console.log('\u00d6\u011fe b\u0131rak\u0131ld\u0131:', el);\n      console.log('Yeni liste:', this.tasks); \/\/ Veri modeli otomatik g\u00fcncellenir\n    });\n  }\n\n  ngOnInit(): void {\n    \/\/ Bile\u015fen y\u00fcklendi\u011finde yap\u0131lacaklar\n  }\n}<\/code><\/pre>\n<p>Yukar\u0131daki kodda, <code>tasks<\/code> ad\u0131nda bir string dizisi tan\u0131mlad\u0131k. <code>DragulaService<\/code>&#8216;i constructor&#8217;da enjekte ederek, s\u00fcr\u00fckleme (<code>drag<\/code>) ve b\u0131rakma (<code>drop<\/code>) gibi olaylar\u0131 dinleyebiliriz. <code>drop<\/code> olay\u0131ndan sonra <code>this.tasks<\/code> dizisinin g\u00fcncellendi\u011fini konsolda g\u00f6rebilirsiniz.<\/p>\n<h3>Minimal CSS<\/h3>\n<p>\u00d6\u011felerin daha belirgin g\u00f6r\u00fcnmesi ve s\u00fcr\u00fckleme s\u0131ras\u0131nda g\u00f6rsel ipu\u00e7lar\u0131 sa\u011flamak i\u00e7in basit bir CSS ekleyebiliriz:<\/p>\n<pre><code class=\"language-scss\">\/<em> src\/app\/app.component.scss <\/em>\/\n.container {\n  max-width: 600px;\n  margin: 50px auto;\n  padding: 20px;\n  border: 1px solid #eee;\n  box-shadow: 0 2px 4px rgba(0,0,0,0.1);\n  border-radius: 8px;\n  background-color: #fff;\n}\n\nh2 {\n  text-align: center;\n  color: #333;\n  margin-bottom: 25px;\n}\n\n.task-list {\n  list-style: none;\n  padding: 0;\n  margin: 0;\n}\n\n.task-item {\n  background-color: #f9f9f9;\n  border: 1px solid #ddd;\n  padding: 15px 20px;\n  margin-bottom: 8px;\n  border-radius: 5px;\n  cursor: grab; \/<em> S\u00fcr\u00fckleyebilece\u011fini belirtmek i\u00e7in <\/em>\/\n  transition: background-color 0.2s ease;\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n\n  &:hover {\n    background-color: #f0f0f0;\n  }\n}\n\n\/<em> S\u00fcr\u00fcklenen \u00f6\u011fe i\u00e7in Dragula'n\u0131n sa\u011flad\u0131\u011f\u0131 \u00f6zel s\u0131n\u0131flar <\/em>\/\n.gu-mirror { \/<em> S\u00fcr\u00fcklenen \u00f6\u011fenin \"ayna\" kopyas\u0131 <\/em>\/\n  opacity: 0.8;\n  background-color: #e0f2f7; \/<em> Hafif mavi arka plan <\/em>\/\n  border: 1px dashed #007bff;\n  box-shadow: 0 4px 8px rgba(0,0,0,0.2);\n  border-radius: 5px;\n  padding: 15px 20px;\n  cursor: grabbing;\n}\n\n.gu-transit { \/<em> S\u00fcr\u00fcklenen \u00f6\u011fenin orijinal yeri bo\u015fkenki hali <\/em>\/\n  opacity: 0;\n}\n\n.gu-hide { \/<em> S\u00fcr\u00fcklenen \u00f6\u011fenin orijinali gizlenir <\/em>\/\n  display: none !important;\n}\n\n\/<em> B\u0131rakma alan\u0131 \u00fczerine gelindi\u011finde <\/em>\/\n.gu-over .task-item {\n  background-color: #e6f7ff; \/<em> Hafif mavi arka plan <\/em>\/\n}<\/code><\/pre>\n<p>Bu temel kurulum ile, <code>tasks<\/code> listesindeki \u00f6\u011feleri s\u00fcr\u00fckleyip b\u0131rakarak s\u0131ralar\u0131n\u0131 de\u011fi\u015ftirebilirsiniz. <code>ng2-dragula<\/code> ve <code>dragulaModel<\/code> sayesinde, arka plandaki <code>tasks<\/code> dizisi otomatik olarak g\u00fcncellenecektir.<\/p>\n<h2>\u0130leri D\u00fczey Kullan\u0131m: \u00c7oklu S\u00fcr\u00fckle ve B\u0131rak Kapsay\u0131c\u0131lar\u0131<\/h2>\n<p>\u00c7o\u011fu zaman, \u00f6\u011feleri sadece tek bir liste i\u00e7inde s\u0131ralamakla kalmay\u0131z; ayn\u0131 zamanda farkl\u0131 listeler veya panolar aras\u0131nda da ta\u015f\u0131mak isteriz. <code>ng2-dragula<\/code>, ayn\u0131 &#8220;bag&#8221; (\u00e7anta\/grup) ad\u0131na sahip birden fazla kapsay\u0131c\u0131 tan\u0131mlayarak bu senaryoyu kolayca y\u00f6netmenizi sa\u011flar.<\/p>\n<h3>\u00d6\u011feleri Gruplama<\/h3>\n<p>Birden fazla kapsay\u0131c\u0131 aras\u0131nda s\u00fcr\u00fckle ve b\u0131rak i\u015flevselli\u011fi sa\u011flamak i\u00e7in, t\u00fcm kapsay\u0131c\u0131lar\u0131n\u0131za ayn\u0131 <code>[dragula]<\/code> grup ad\u0131n\u0131 vermeniz yeterlidir.<\/p>\n<pre><code class=\"language-html\"><!-- src\/app\/app.component.html -->\n<div class=\"board-container\">\n  <div class=\"board-column\">\n    <h3>Yap\u0131lacaklar<\/h3>\n    <ul [dragula]=\"'task-board'\" [(dragulaModel)]=\"todoTasks\" class=\"task-list\">\n      <li *ngFor=\"let task of todoTasks\" class=\"task-item\">{{ task.name }}<\/li>\n    <\/ul>\n  <\/div>\n\n  <div class=\"board-column\">\n    <h3>Devam Edenler<\/h3>\n    <ul [dragula]=\"'task-board'\" [(dragulaModel)]=\"inProgressTasks\" class=\"task-list\">\n      <li *ngFor=\"let task of inProgressTasks\" class=\"task-item\">{{ task.name }}<\/li>\n    <\/ul>\n  <\/div>\n\n  <div class=\"board-column\">\n    <h3>Tamamlananlar<\/h3>\n    <ul [dragula]=\"'task-board'\" [(dragulaModel)]=\"doneTasks\" class=\"task-list\">\n      <li *ngFor=\"let task of doneTasks\" class=\"task-item\">{{ task.name }}<\/li>\n    <\/ul>\n  <\/div>\n<\/div><\/code><\/pre>\n<p>Burada \u00fc\u00e7 farkl\u0131 <code>ul<\/code> elementi var, her biri <code>task-board<\/code> ad\u0131nda ayn\u0131 <code>[dragula]<\/code> grubuna ait. Bu sayede, bir <code>ul<\/code>&#8216;den di\u011ferine \u00f6\u011fe s\u00fcr\u00fckleyip b\u0131rakmak m\u00fcmk\u00fcn olacak. Ayr\u0131ca, <code>tasks<\/code> dizisi yerine <code>task<\/code> nesneleri kullan\u0131yoruz, bu da ger\u00e7ek d\u00fcnya senaryolar\u0131na daha uygun.<\/p>\n<h3>Bile\u015fen Mant\u0131\u011f\u0131<\/h3>\n<p>Bile\u015feninizde, her bir liste i\u00e7in ayr\u0131 bir dizi tan\u0131mlaman\u0131z gerekecek:<\/p>\n<pre><code class=\"language-typescript\">\/\/ src\/app\/app.component.ts\nimport { Component, OnInit, OnDestroy } from '@angular\/core';\nimport { DragulaService } from 'ng2-dragula';\nimport { Subscription } from 'rxjs';\n\ninterface Task {\n  id: number;\n  name: string;\n  status: 'todo' | 'in-progress' | 'done';\n}\n\n@Component({\n  selector: 'app-root',\n  templateUrl: '.\/app.component.html',\n  styleUrls: ['.\/app.component.scss']\n})\nexport class AppComponent implements OnInit, OnDestroy {\n  title = 'my-drag-drop-app';\n  todoTasks: Task[] = [\n    { id: 1, name: 'Proje dok\u00fcmantasyonunu haz\u0131rla', status: 'todo' },\n    { id: 2, name: 'API entegrasyonunu tamamla', status: 'todo' }\n  ];\n  inProgressTasks: Task[] = [\n    { id: 3, name: 'Kullan\u0131c\u0131 aray\u00fcz\u00fcn\u00fc tasarla', status: 'in-progress' }\n  ];\n  doneTasks: Task[] = [\n    { id: 4, name: 'Veritaban\u0131 \u015femas\u0131n\u0131 olu\u015ftur', status: 'done' }\n  ];\n\n  private subs = new Subscription(); \/\/ Abonelikleri y\u00f6netmek i\u00e7in\n\n  constructor(private dragulaService: DragulaService) {\n    this.subs.add(this.dragulaService.dropModel('task-board').subscribe(({ el, target, source, sourceModel, targetModel, item }) => {\n      console.log('\u00d6\u011fe b\u0131rak\u0131ld\u0131 ve model g\u00fcncellendi:', item);\n      console.log('Kaynak Model:', sourceModel);\n      console.log('Hedef Model:', targetModel);\n\n      \/\/ Bu noktada, veritaban\u0131 veya API'nizi g\u00fcncellemek i\u00e7in gerekli mant\u0131\u011f\u0131 yazabilirsiniz.\n      \/\/ \u00d6rne\u011fin, item.status'u g\u00fcncelleyip bir API \u00e7a\u011fr\u0131s\u0131 yapabilirsiniz.\n      if (target.classList.contains('todo-list')) { \/\/ \u00d6rnek bir kontrol\n        item.status = 'todo';\n      } else if (target.classList.contains('in-progress-list')) {\n        item.status = 'in-progress';\n      } else if (target.classList.contains('done-list')) {\n        item.status = 'done';\n      }\n      console.log('G\u00fcncellenmi\u015f \u00f6\u011fe:', item);\n    }));\n\n    this.subs.add(this.dragulaService.removeModel('task-board').subscribe(({ el, source, sourceModel, item }) => {\n      console.log('\u00d6\u011fe kaynaktan kald\u0131r\u0131ld\u0131:', item);\n      \/\/ \u00d6\u011fenin kald\u0131r\u0131ld\u0131\u011f\u0131 durumu y\u00f6netebilirsiniz (\u00f6rne\u011fin, bir \u00e7\u00f6p kutusuna s\u00fcr\u00fckleme).\n    }));\n  }\n\n  ngOnInit(): void {\n    \/\/ Bile\u015fen y\u00fcklendi\u011finde yap\u0131lacaklar\n  }\n\n  ngOnDestroy(): void {\n    this.subs.unsubscribe(); \/\/ Bellek s\u0131z\u0131nt\u0131lar\u0131n\u0131 \u00f6nlemek i\u00e7in abonelikleri iptal et\n  }\n}<\/code><\/pre>\n<p>Bu \u00f6rnekte, <code>Task<\/code> aray\u00fcz\u00fc ile daha karma\u015f\u0131k bir veri yap\u0131s\u0131 kulland\u0131k. <code>dragulaService.dropModel<\/code> olay\u0131n\u0131 dinleyerek, bir \u00f6\u011fe b\u0131rak\u0131ld\u0131\u011f\u0131nda hem kaynak hem de hedef veri modellerine eri\u015febiliriz. <code>item<\/code> parametresi, ta\u015f\u0131nan \u00f6\u011fenin kendisini i\u00e7erir. Bu sayede, \u00f6\u011fenin durumunu (\u00f6rne\u011fin <code>status<\/code> \u00f6zelli\u011fini) g\u00fcncelleyebilir ve bu de\u011fi\u015fikli\u011fi bir arka u\u00e7 servisine bildirebilirsiniz. <code>ngOnDestroy<\/code> i\u00e7inde abonelikleri temizlemek, bellek s\u0131z\u0131nt\u0131lar\u0131n\u0131 \u00f6nlemek i\u00e7in iyi bir pratiktir.<\/p>\n<h3>CSS D\u00fczenlemesi<\/h3>\n<p>Kanban benzeri bir pano g\u00f6r\u00fcn\u00fcm\u00fc i\u00e7in CSS&#8217;i biraz daha geli\u015ftirebiliriz:<\/p>\n<pre><code class=\"language-scss\">\/<em> src\/app\/app.component.scss <\/em>\/\n.board-container {\n  display: flex;\n  justify-content: space-around;\n  margin: 50px auto;\n  max-width: 1200px;\n  gap: 20px; \/<em> S\u00fctunlar aras\u0131 bo\u015fluk <\/em>\/\n}\n\n.board-column {\n  flex: 1;\n  min-width: 300px;\n  background-color: #f8f9fa;\n  border: 1px solid #e9ecef;\n  border-radius: 8px;\n  padding: 15px;\n  box-shadow: 0 2px 5px rgba(0,0,0,0.05);\n\n  h3 {\n    text-align: center;\n    color: #495057;\n    margin-bottom: 20px;\n    padding-bottom: 10px;\n    border-bottom: 1px solid #dee2e6;\n  }\n}\n\n.task-list {\n  list-style: none;\n  padding: 0;\n  min-height: 100px; \/<em> Bo\u015fken bile b\u0131rakma alan\u0131 olmas\u0131 i\u00e7in <\/em>\/\n  margin: 0;\n}\n\n.task-item {\n  background-color: #ffffff;\n  border: 1px solid #ced4da;\n  padding: 12px 15px;\n  margin-bottom: 10px;\n  border-radius: 6px;\n  cursor: grab;\n  transition: all 0.2s ease-in-out;\n  box-shadow: 0 1px 3px rgba(0,0,0,0.08);\n\n  &:hover {\n    background-color: #e9ecef;\n    box-shadow: 0 2px 6px rgba(0,0,0,0.1);\n  }\n}\n\n\/<em> Dragula'n\u0131n \u00f6zel s\u0131n\u0131flar\u0131 <\/em>\/\n.gu-mirror {\n  opacity: 0.8;\n  background-color: #d1ecf1; \/<em> Hafif mavi <\/em>\/\n  border: 1px dashed #007bff;\n  box-shadow: 0 4px 10px rgba(0,0,0,0.2);\n  transform: rotate(2deg); \/<em> Hafif bir rotasyon efekti <\/em>\/\n}\n\n.gu-transit {\n  opacity: 0;\n}\n\n.gu-hide {\n  display: none !important;\n}\n\n.gu-unselectable {\n  -webkit-user-select: none;\n  -moz-user-select: none;\n  -ms-user-select: none;\n  user-select: none;\n}\n\n.gu-over .task-list { \/<em> B\u0131rakma alan\u0131 \u00fczerine gelindi\u011finde <\/em>\/\n  background-color: #e2f0ff; \/<em> Daha belirgin bir mavi <\/em>\/\n  border-color: #007bff;\n}<\/code><\/pre>\n<p>Bu CSS ile, Kanban benzeri \u00fc\u00e7 s\u00fctunlu bir pano elde edersiniz ve \u00f6\u011feleri s\u00fcr\u00fckleyip b\u0131rakarak durumlar\u0131n\u0131 de\u011fi\u015ftirebilirsiniz. <code>dragulaModel<\/code> sayesinde, arka plandaki veri dizileri de otomatik olarak g\u00fcncellenir.<\/p>\n<h2>S\u00fcr\u00fckle ve B\u0131rak Davran\u0131\u015f\u0131n\u0131 \u00d6zelle\u015ftirme<\/h2>\n<p><code>ng2-dragula<\/code>, s\u00fcr\u00fckle ve b\u0131rak davran\u0131\u015f\u0131n\u0131 ihtiya\u00e7lar\u0131n\u0131za g\u00f6re ayarlaman\u0131z i\u00e7in zengin bir API sunar. Bu \u00f6zelle\u015ftirmeler genellikle iki ana yolla yap\u0131l\u0131r: <code>DragulaService<\/code> olaylar\u0131n\u0131 dinleyerek ve grup se\u00e7eneklerini (<code>options<\/code>) ayarlayarak.<\/p>\n<h3>DragulaService Olaylar\u0131<\/h3>\n<p><code>DragulaService<\/code>, s\u00fcr\u00fckle ve b\u0131rak ya\u015fam d\u00f6ng\u00fcs\u00fcndeki \u00e7e\u015fitli noktalarda tetiklenen bir dizi olay sa\u011flar. Bu olaylara abone olarak, uygulaman\u0131z\u0131n belirli durumlarda \u00f6zel mant\u0131k y\u00fcr\u00fctmesini sa\u011flayabilirsiniz. En yayg\u0131n olaylar \u015funlard\u0131r:<\/p>\n<p>*   <strong><code>drag(bagName)<\/code>:<\/strong> Bir \u00f6\u011fe s\u00fcr\u00fcklenmeye ba\u015flad\u0131\u011f\u0131nda tetiklenir.<br \/>\n*   <strong><code>drop(bagName)<\/code>:<\/strong> Bir \u00f6\u011fe ge\u00e7erli bir b\u0131rakma alan\u0131na b\u0131rak\u0131ld\u0131\u011f\u0131nda tetiklenir.<br \/>\n*   <strong><code>over(bagName)<\/code>:<\/strong> S\u00fcr\u00fcklenen \u00f6\u011fe bir kapsay\u0131c\u0131n\u0131n \u00fczerine geldi\u011finde tetiklenir.<br \/>\n*   <strong><code>out(bagName)<\/code>:<\/strong> S\u00fcr\u00fcklenen \u00f6\u011fe bir kapsay\u0131c\u0131dan \u00e7\u0131kt\u0131\u011f\u0131nda tetiklenir.<br \/>\n*   <strong><code>remove(bagName)<\/code>:<\/strong> Bir \u00f6\u011fe bir kapsay\u0131c\u0131dan \u00e7\u0131kar\u0131ld\u0131\u011f\u0131nda (\u00f6rne\u011fin <code>removeOnSpill<\/code> true ise) tetiklenir.<br \/>\n*   <strong><code>cancel(bagName)<\/code>:<\/strong> S\u00fcr\u00fckleme i\u015flemi iptal edildi\u011finde (\u00f6rne\u011fin ge\u00e7ersiz bir alana b\u0131rak\u0131ld\u0131\u011f\u0131nda) tetiklenir.<br \/>\n*   <strong><code>cloned(bagName)<\/code>:<\/strong> S\u00fcr\u00fcklenen \u00f6\u011fenin kopyas\u0131 olu\u015fturuldu\u011funda tetiklenir (yaln\u0131zca <code>copy<\/code> se\u00e7ene\u011fi true ise).<br \/>\n*   <strong><code>shadow(bagName)<\/code>:<\/strong> S\u00fcr\u00fcklenen \u00f6\u011fenin g\u00f6lge (yer tutucu) \u00f6\u011fesi ta\u015f\u0131nd\u0131\u011f\u0131nda tetiklenir.<br \/>\n*   <strong><code>dropModel(bagName)<\/code>:<\/strong> <code>[(dragulaModel)]<\/code> kullan\u0131l\u0131yorsa, \u00f6\u011fe b\u0131rak\u0131ld\u0131\u011f\u0131nda ve model g\u00fcncellendi\u011finde tetiklenir. Bu, genellikle model g\u00fcncellemelerini yakalamak i\u00e7in en kullan\u0131\u015fl\u0131 olayd\u0131r.<br \/>\n*   <strong><code>removeModel(bagName)<\/code>:<\/strong> <code>[(dragulaModel)]<\/code> kullan\u0131l\u0131yorsa, \u00f6\u011fe modelden kald\u0131r\u0131ld\u0131\u011f\u0131nda tetiklenir.<\/p>\n<p>Bu olaylara <code>DragulaService<\/code> \u00fczerinden abone olabilirsiniz:<\/p>\n<pre><code class=\"language-typescript\">\/\/ app.component.ts i\u00e7inde\nimport { DragulaService } from 'ng2-dragula';\nimport { Subscription } from 'rxjs';\n\n\/\/ ... (di\u011fer importlar)\n\nexport class AppComponent implements OnInit, OnDestroy {\n  \/\/ ... (di\u011fer \u00f6zellikler)\n  private subs = new Subscription();\n\n  constructor(private dragulaService: DragulaService) {\n    \/\/ Drop olay\u0131n\u0131 dinleme\n    this.subs.add(this.dragulaService.drop('task-board').subscribe(({ el, target, source, sibling }) => {\n      console.log('Drop event: Bir \u00f6\u011fe b\u0131rak\u0131ld\u0131.');\n      \/\/ el: B\u0131rak\u0131lan HTML elementi\n      \/\/ target: \u00d6\u011fenin b\u0131rak\u0131ld\u0131\u011f\u0131 kapsay\u0131c\u0131 HTML elementi\n      \/\/ source: \u00d6\u011fenin geldi\u011fi kapsay\u0131c\u0131 HTML elementi\n      \/\/ sibling: \u00d6\u011fenin b\u0131rak\u0131ld\u0131\u011f\u0131 yerdeki kom\u015fu HTML elementi (varsa)\n    }));\n\n    \/\/ dropModel olay\u0131n\u0131 dinleme (veri modelini g\u00fcncellemek i\u00e7in daha uygun)\n    this.subs.add(this.dragulaService.dropModel('task-board').subscribe(({ el, target, source, sourceModel, targetModel, item }) => {\n      console.log('dropModel event: Veri modeli g\u00fcncellendi.');\n      console.log('Ta\u015f\u0131nan \u00f6\u011fe:', item);\n      \/\/ item: Ta\u015f\u0131nan \u00f6\u011fenin kendisi (veri modelindeki nesne)\n      \/\/ sourceModel: Kaynak liste (dizi)\n      \/\/ targetModel: Hedef liste (dizi)\n\n      \/\/ \u00d6rnek: \u00d6\u011fenin durumunu g\u00fcncelle ve bir API \u00e7a\u011fr\u0131s\u0131 yap\n      if (target.id === 'todo-list') {\n        item.status = 'todo';\n      } else if (target.id === 'in-progress-list') {\n        item.status = 'in-progress';\n      } else if (target.id === 'done-list') {\n        item.status = 'done';\n      }\n      \/\/ this.taskService.updateTask(item).subscribe(); \/\/ Ger\u00e7ek bir senaryoda bu \u015fekilde kullan\u0131labilir\n    }));\n\n    \/\/ drag olay\u0131n\u0131 dinleme\n    this.subs.add(this.dragulaService.drag('task-board').subscribe(({ el, source }) => {\n      console.log('Drag event: Bir \u00f6\u011fe s\u00fcr\u00fckleniyor.');\n      \/\/ el: S\u00fcr\u00fcklenen HTML elementi\n      \/\/ source: \u00d6\u011fenin geldi\u011fi kapsay\u0131c\u0131 HTML elementi\n      \/\/ S\u00fcr\u00fckleme ba\u015flad\u0131\u011f\u0131nda g\u00f6rsel bir ipucu vermek i\u00e7in kullan\u0131labilir\n      el.classList.add('is-dragging');\n    }));\n\n    this.subs.add(this.dragulaService.cancel('task-board').subscribe(({ el, container, source }) => {\n      console.log('Cancel event: S\u00fcr\u00fckleme iptal edildi.');\n      el.classList.remove('is-dragging');\n    }));\n\n    this.subs.add(this.dragulaService.over('task-board').subscribe(({ el, container, source }) => {\n      console.log('Over event: Bir kapsay\u0131c\u0131 \u00fczerine gelindi.');\n      container.classList.add('gu-over-highlight');\n    }));\n\n    this.subs.add(this.dragulaService.out('task-board').subscribe(({ el, container, source }) => {\n      console.log('Out event: Bir kapsay\u0131c\u0131dan \u00e7\u0131k\u0131ld\u0131.');\n      container.classList.remove('gu-over-highlight');\n    }));\n  }\n\n  ngOnDestroy(): void {\n    this.subs.unsubscribe(); \/\/ Abonelikleri temizle\n  }\n}<\/code><\/pre>\n<p>Bu olaylar\u0131 dinleyerek, s\u00fcr\u00fckle ve b\u0131rak i\u015flemlerinin her a\u015famas\u0131nda \u00f6zel mant\u0131k y\u00fcr\u00fctebilir, g\u00f6rsel geri bildirim sa\u011flayabilir ve veri modelinizi senkronize edebilirsiniz.<\/p>\n<h3>Dragula Se\u00e7enekleri (Options)<\/h3>\n<p><code>ng2-dragula<\/code>, <code>dragula<\/code> k\u00fct\u00fcphanesinin temel se\u00e7eneklerini destekler. Bu se\u00e7enekleri kullanarak s\u00fcr\u00fckle ve b\u0131rak davran\u0131\u015f\u0131n\u0131 daha ayr\u0131nt\u0131l\u0131 bir \u015fekilde kontrol edebilirsiniz. Se\u00e7enekleri, <code>DragulaService.createGroup()<\/code> metodunu kullanarak tan\u0131mlars\u0131n\u0131z:<\/p>\n<pre><code class=\"language-typescript\">\/\/ app.component.ts i\u00e7inde, constructor'da veya ngOnInit'te\nimport { DragulaService } from 'ng2-dragula';\n\nexport class AppComponent implements OnInit {\n  \/\/ ...\n\n  constructor(private dragulaService: DragulaService) {\n    this.dragulaService.createGroup('my-custom-bag', {\n      \/\/ Se\u00e7enekleri burada tan\u0131mlay\u0131n\n      moves: (el, source, handle, sibling) => {\n        \/\/ el: S\u00fcr\u00fcklenen element\n        \/\/ source: Kaynak kapsay\u0131c\u0131\n        \/\/ handle: S\u00fcr\u00fcklemeyi ba\u015flatan element\n        \/\/ sibling: S\u00fcr\u00fcklenen elementin kom\u015fusu\n        \/\/ Sadece belirli bir s\u0131n\u0131fa sahip \u00f6\u011felerin s\u00fcr\u00fcklenmesine izin ver\n        return handle.classList.contains('draggable-item');\n      },\n      accepts: (el, target, source, sibling) => {\n        \/\/ el: S\u00fcr\u00fcklenen element\n        \/\/ target: Hedef kapsay\u0131c\u0131\n        \/\/ source: Kaynak kapsay\u0131c\u0131\n        \/\/ sibling: Hedefteki kom\u015fu element\n        \/\/ Sadece 'todo' listesinden 'in-progress' listesine s\u00fcr\u00fcklemeye izin ver\n        return source.id === 'todo-list' && target.id === 'in-progress-list';\n      },\n      copy: false, \/\/ \u00d6\u011feyi s\u00fcr\u00fcklerken kopyala (true) veya ta\u015f\u0131 (false)\n      revertOnSpill: true, \/\/ Ge\u00e7ersiz bir alana b\u0131rak\u0131ld\u0131\u011f\u0131nda \u00f6\u011feyi geri yerine koy\n      removeOnSpill: false, \/\/ Ge\u00e7ersiz bir alana b\u0131rak\u0131ld\u0131\u011f\u0131nda \u00f6\u011feyi tamamen kald\u0131r\n      direction: 'vertical', \/\/ S\u00fcr\u00fckleme y\u00f6n\u00fc: 'horizontal' veya 'vertical'\n      mirrorContainer: document.body, \/\/ S\u00fcr\u00fcklenen \u00f6\u011fenin kopyas\u0131n\u0131n eklenece\u011fi kapsay\u0131c\u0131\n      ignoreInputTextSelection: true \/\/ Metin giri\u015f alanlar\u0131ndaki se\u00e7imi yok say\n    });\n\n    \/\/ ... (di\u011fer olay abonelikleri)\n  }\n\n  ngOnInit(): void {\n    \/\/ HTML'de bu grubu kullanmak i\u00e7in:\n    \/\/ <ul [dragula]=\"'my-custom-bag'\" [(dragulaModel)]=\"items\">...<\/ul>\n  }\n}<\/code><\/pre>\n<p>Yayg\u0131n kullan\u0131lan baz\u0131 se\u00e7enekler ve a\u00e7\u0131klamalar\u0131:<\/p>\n<p>*   <strong><code>moves(el, source, handle, sibling)<\/code> (function):<\/strong> Bir \u00f6\u011fenin s\u00fcr\u00fcklenip s\u00fcr\u00fcklenemeyece\u011fini belirler. <code>true<\/code> d\u00f6nerse s\u00fcr\u00fcklemeye izin verilir, <code>false<\/code> d\u00f6nerse engellenir. Bu fonksiyon, belirli \u00f6\u011feleri s\u00fcr\u00fcklenemez yapmak veya sadece belirli bir &#8220;handle&#8221; (tutacak) \u00fczerinden s\u00fcr\u00fcklemeye izin vermek i\u00e7in \u00e7ok kullan\u0131\u015fl\u0131d\u0131r.<br \/>\n*   <strong><code>accepts(el, target, source, sibling)<\/code> (function):<\/strong> Bir \u00f6\u011fenin belirli bir hedef kapsay\u0131c\u0131ya b\u0131rak\u0131l\u0131p b\u0131rak\u0131lamayaca\u011f\u0131n\u0131 belirler. <code>true<\/code> d\u00f6nerse b\u0131rakmaya izin verilir. Bu, kurall\u0131 b\u0131rakma alanlar\u0131 olu\u015fturmak i\u00e7in harikad\u0131r (\u00f6rne\u011fin, &#8220;Tamamland\u0131&#8221; s\u00fctununa sadece &#8220;Devam Ediyor&#8221; \u00f6\u011felerinin b\u0131rak\u0131lmas\u0131na izin vermek).<br \/>\n*   <strong><code>copy<\/code> (boolean):<\/strong> <code>true<\/code> olarak ayarlan\u0131rsa, s\u00fcr\u00fcklenen \u00f6\u011fe kopyalan\u0131r ve orijinali yerinde kal\u0131r. <code>false<\/code> ise \u00f6\u011fe ta\u015f\u0131n\u0131r.<br \/>\n*   <strong><code>revertOnSpill<\/code> (boolean):<\/strong> <code>true<\/code> ise, bir \u00f6\u011fe ge\u00e7erli bir b\u0131rakma alan\u0131 d\u0131\u015f\u0131na b\u0131rak\u0131ld\u0131\u011f\u0131nda orijinal konumuna geri d\u00f6ner.<br \/>\n*   <strong><code>removeOnSpill<\/code> (boolean):<\/strong> <code>true<\/code> ise, bir \u00f6\u011fe ge\u00e7erli bir b\u0131rakma alan\u0131 d\u0131\u015f\u0131na b\u0131rak\u0131ld\u0131\u011f\u0131nda tamamen kald\u0131r\u0131l\u0131r. Bu, bir \u00e7\u00f6p kutusu i\u015flevi olu\u015fturmak i\u00e7in kullan\u0131labilir.<br \/>\n*   <strong><code>direction<\/code> (string):<\/strong> S\u00fcr\u00fckleme y\u00f6n\u00fcn\u00fc belirler: <code>'vertical'<\/code> (varsay\u0131lan) veya <code>'horizontal'<\/code>.<br \/>\n*   <strong><code>mirrorContainer<\/code> (HTMLElement):<\/strong> S\u00fcr\u00fcklenen \u00f6\u011fenin &#8220;ayna&#8221; kopyas\u0131n\u0131n eklenece\u011fi DOM elementi. Varsay\u0131lan olarak <code>document.body<\/code>&#8216;dir.<br \/>\n*   <strong><code>ignoreInputTextSelection<\/code> (boolean):<\/strong> <code>true<\/code> ise, metin giri\u015f alanlar\u0131ndaki (input, textarea) metin se\u00e7imi s\u00fcr\u00fckleme i\u015flemini ba\u015flatmaz.<\/p>\n<p>Bu se\u00e7enekleri kullanarak, uygulaman\u0131z\u0131n s\u00fcr\u00fckle ve b\u0131rak etkile\u015fimlerini hassas bir \u015fekilde kontrol edebilir ve kullan\u0131c\u0131lar\u0131n\u0131z i\u00e7in \u00f6zel deneyimler olu\u015fturabilirsiniz.<\/p>\n<h2>Ger\u00e7ek D\u00fcnya Senaryolar\u0131 ve En \u0130yi Uygulamalar<\/h2>\n<p><code>ng2-dragula<\/code>&#8216;y\u0131 ger\u00e7ek d\u00fcnya Angular uygulamalar\u0131na entegre ederken g\u00f6z \u00f6n\u00fcnde bulundurman\u0131z gereken baz\u0131 \u00f6nemli noktalar ve en iyi uygulamalar vard\u0131r.<\/p>\n<h3>Durumu Kaydetme (Persisting State)<\/h3>\n<p>S\u00fcr\u00fckle ve b\u0131rak i\u015flemleri genellikle uygulaman\u0131n durumunu de\u011fi\u015ftirir. Bu de\u011fi\u015fikliklerin kullan\u0131c\u0131 oturumlar\u0131 aras\u0131nda veya farkl\u0131 cihazlarda kal\u0131c\u0131 olmas\u0131 i\u00e7in, durumu bir arka u\u00e7 servisine (API) veya yerel depolamaya kaydetmeniz gerekir.<\/p>\n<p><code>dragulaService.dropModel()<\/code> olay\u0131, bu i\u015flem i\u00e7in ideal bir yerdir. Bu olay tetiklendi\u011finde, <code>targetModel<\/code> ve <code>item<\/code> gibi parametrelere eri\u015ferek de\u011fi\u015fen veriyi alabilir ve bir HTTP iste\u011fi ile API&#8217;nize g\u00f6nderebilirsiniz:<\/p>\n<pre><code class=\"language-typescript\">\/\/ app.component.ts i\u00e7inde dropModel aboneli\u011fi\nthis.subs.add(this.dragulaService.dropModel('task-board').subscribe(({ el, target, source, sourceModel, targetModel, item }) => {\n  console.log('\u00d6\u011fe b\u0131rak\u0131ld\u0131 ve model g\u00fcncellendi:', item);\n\n  \/\/ \u00d6\u011fenin yeni konumuna g\u00f6re durumunu g\u00fcncelle\n  if (target.id === 'todo-list') {\n    item.status = 'todo';\n  } else if (target.id === 'in-progress-list') {\n    item.status = 'in-progress';\n  } else if (target.id === 'done-list') {\n    item.status = 'done';\n  }\n\n  \/\/ API'ye g\u00fcncelleme iste\u011fi g\u00f6nder\n  \/\/ this.taskService.updateTask(item.id, { status: item.status, order: targetModel.indexOf(item) })\n  \/\/   .subscribe(\n  \/\/     response => console.log('G\u00f6rev g\u00fcncellendi:', response),\n  \/\/     error => console.error('G\u00fcncelleme hatas\u0131:', error)\n  \/\/   );\n\n  \/\/ Ayr\u0131ca, targetModel'in yeni s\u0131ralamas\u0131n\u0131 da kaydetmek isteyebilirsiniz.\n  \/\/ targetModel.forEach((task, index) => {\n  \/\/   this.taskService.updateTask(task.id, { order: index }).subscribe();\n  \/\/ });\n}));<\/code><\/pre>\n<p>Bu yakla\u015f\u0131m, kullan\u0131c\u0131 bir \u00f6\u011feyi s\u00fcr\u00fckleyip b\u0131rakt\u0131\u011f\u0131nda, uygulaman\u0131z\u0131n arka plandaki veritaban\u0131n\u0131 veya di\u011fer kal\u0131c\u0131 depolama alanlar\u0131n\u0131 g\u00fcncelleyebilmesini sa\u011flar.<\/p>\n<h3>Karma\u015f\u0131k Veri Yap\u0131lar\u0131<\/h3>\n<p>Yukar\u0131daki \u00f6rneklerde <code>Task<\/code> aray\u00fcz\u00fc ile basit objeler kulland\u0131k. Ger\u00e7ek uygulamalarda, \u00f6\u011feleriniz daha karma\u015f\u0131k i\u00e7 i\u00e7e ge\u00e7mi\u015f objeler i\u00e7erebilir. <code>ng2-dragula<\/code>, <code>[(dragulaModel)]<\/code> direktifi sayesinde bu t\u00fcr karma\u015f\u0131k veri yap\u0131lar\u0131yla da sorunsuz \u00e7al\u0131\u015f\u0131r. <code>dropModel<\/code> olay\u0131, ta\u015f\u0131nan \u00f6\u011fenin t\u00fcm orijinal \u00f6zelliklerini i\u00e7eren <code>item<\/code> parametresini sa\u011flar.<\/p>\n<h3>Eri\u015filebilirlik (Accessibility)<\/h3>\n<p>S\u00fcr\u00fckle ve b\u0131rak aray\u00fczleri, fare veya dokunmatik ekran kullan\u0131c\u0131lar\u0131 i\u00e7in sezgisel olsa da, klavye veya yard\u0131mc\u0131 teknoloji kullanan kullan\u0131c\u0131lar i\u00e7in eri\u015filebilirlik sorunlar\u0131 yaratabilir. <code>ng2-dragula<\/code> varsay\u0131lan olarak klavye eri\u015filebilirli\u011fi sa\u011flamaz. Eri\u015filebilir bir s\u00fcr\u00fckle ve b\u0131rak deneyimi sunmak i\u00e7in ek \u00e7aba sarf etmeniz gerekebilir:<\/p>\n<p>*   <strong>Klavye Kontrolleri:<\/strong> \u00d6\u011feleri klavye ile se\u00e7me, ta\u015f\u0131ma ve b\u0131rakma mekanizmalar\u0131 ekleyin (\u00f6rne\u011fin, ok tu\u015flar\u0131 ile ta\u015f\u0131ma, Enter tu\u015fu ile b\u0131rakma).<br \/>\n*   <strong>ARIA Nitelikleri:<\/strong> \u00d6\u011felere ve kapsay\u0131c\u0131lara <code>aria-grabbed<\/code>, <code>aria-dropeffect<\/code>, <code>aria-labelledby<\/code> gibi ARIA nitelikleri ekleyerek yard\u0131mc\u0131 teknolojilere bilgi sa\u011flay\u0131n.<br \/>\n*   <strong>Alternatif Giri\u015f Yollar\u0131:<\/strong> S\u00fcr\u00fckle ve b\u0131rak yerine, \u00f6\u011feleri ta\u015f\u0131mak i\u00e7in alternatif d\u00fc\u011fmeler veya a\u00e7\u0131l\u0131r men\u00fcler sunmay\u0131 d\u00fc\u015f\u00fcn\u00fcn.<\/p>\n<h3>Performans<\/h3>\n<p>\u00c7ok say\u0131da \u00f6\u011fe (\u00f6rne\u011fin y\u00fczlerce veya binlerce) i\u00e7eren listelerde s\u00fcr\u00fckle ve b\u0131rak kullan\u0131rken performans sorunlar\u0131 ya\u015fanabilir. <code>ng2-dragula<\/code> genellikle hafiftir, ancak DOM manip\u00fclasyonlar\u0131 b\u00fcy\u00fck listelerde yava\u015flayabilir.<\/p>\n<p>*   <strong>Sanal Kayd\u0131rma (Virtual Scrolling):<\/strong> <code>@angular\/cdk\/scrolling<\/code> gibi k\u00fct\u00fcphaneleri kullanarak sadece g\u00f6r\u00fcn\u00fcrdeki \u00f6\u011feleri render edin. Bu, DOM boyutunu k\u00fc\u00e7\u00fclterek performans\u0131 art\u0131r\u0131r. Ancak, sanal kayd\u0131rma ile s\u00fcr\u00fckle ve b\u0131rak entegrasyonu bazen karma\u015f\u0131k olabilir.<br \/>\n*   <strong>Gereksiz Yeniden Render Etmeleri \u00d6nleme:<\/strong> <code>OnPush<\/code> de\u011fi\u015fiklik alg\u0131lama stratejisini kullanarak bile\u015fenlerinizin yaln\u0131zca giri\u015f verileri de\u011fi\u015fti\u011finde yeniden render edilmesini sa\u011flay\u0131n.<\/p>\n<h3>Stil ve G\u00f6rsel Geri Bildirim<\/h3>\n<p>Kullan\u0131c\u0131lara s\u00fcr\u00fckleme ve b\u0131rakma i\u015flemleri hakk\u0131nda net g\u00f6rsel geri bildirim sa\u011flamak, kullan\u0131c\u0131 deneyimini iyile\u015ftirir.<\/p>\n<p>*   <strong>S\u00fcr\u00fcklenen \u00d6\u011fenin Stili:<\/strong> <code>gu-mirror<\/code> s\u0131n\u0131f\u0131n\u0131 kullanarak s\u00fcr\u00fcklenen \u00f6\u011fenin kopyas\u0131n\u0131 \u00f6zelle\u015ftirin. Opakl\u0131k, g\u00f6lge veya hafif bir d\u00f6nd\u00fcrme efekti ekleyebilirsiniz.<br \/>\n*   <strong>Kaynak \u00d6\u011fenin Stili:<\/strong> <code>gu-transit<\/code> s\u0131n\u0131f\u0131, s\u00fcr\u00fcklenen \u00f6\u011fenin orijinal yerini temsil eder. Genellikle bu \u00f6\u011fenin opakl\u0131\u011f\u0131n\u0131 azaltarak veya tamamen gizleyerek kullan\u0131c\u0131n\u0131n nereye b\u0131rakaca\u011f\u0131n\u0131 daha net g\u00f6rmesini sa\u011flar\u0131z.<br \/>\n*   <strong>B\u0131rakma Alan\u0131n\u0131n Stili:<\/strong> <code>gu-over<\/code> s\u0131n\u0131f\u0131, s\u00fcr\u00fcklenen \u00f6\u011fe bir kapsay\u0131c\u0131n\u0131n \u00fczerine geldi\u011finde kapsay\u0131c\u0131ya eklenir. Bu s\u0131n\u0131f\u0131 kullanarak, bir b\u0131rakma alan\u0131n\u0131n aktif oldu\u011funu g\u00f6steren bir vurgu (\u00f6rne\u011fin, kenarl\u0131k rengi veya arka plan rengi de\u011fi\u015fikli\u011fi) ekleyebilirsiniz.<br \/>\n*   <strong>&#8220;Handle&#8221; (Tutacak) Kullan\u0131m\u0131:<\/strong> E\u011fer \u00f6\u011felerin sadece belirli bir k\u0131sm\u0131ndan s\u00fcr\u00fcklenmesini istiyorsan\u0131z, <code>moves<\/code> se\u00e7ene\u011fini kullanarak bir &#8220;handle&#8221; tan\u0131mlay\u0131n. Bu, \u00f6zellikle karma\u015f\u0131k \u00f6\u011felerde yanl\u0131\u015fl\u0131kla s\u00fcr\u00fcklemeyi \u00f6nler.<\/p>\n<pre><code class=\"language-html\"><!-- Sadece bu div'den s\u00fcr\u00fcklemeye izin ver -->\n<li class=\"task-item\">\n  <div class=\"drag-handle draggable-item\">::<\/div>\n  <span>{{ task.name }}<\/span>\n<\/li><\/code><\/pre>\n<p>Ve <code>moves<\/code> se\u00e7ene\u011finde <code>handle.classList.contains('draggable-item')<\/code> kontrol\u00fcn\u00fc yap\u0131n.<\/p>\n<h2>Sorun Giderme ve S\u0131k Kar\u015f\u0131la\u015f\u0131lan Sorunlar<\/h2>\n<p><code>ng2-dragula<\/code> kullan\u0131rken kar\u015f\u0131la\u015fabilece\u011finiz baz\u0131 yayg\u0131n sorunlar ve \u00e7\u00f6z\u00fcmleri:<\/p>\n<p>*   <strong>S\u00fcr\u00fckle ve B\u0131rak \u00c7al\u0131\u015fm\u0131yor:<\/strong><br \/>\n    *   <code>DragulaModule.forRoot()<\/code>&#8216;\u0131 <code>app.module.ts<\/code>&#8216;e veya <code>DragulaModule<\/code>&#8216;\u00fc ilgili feature mod\u00fcl\u00fcne <code>imports<\/code> dizisine ekledi\u011finizden emin olun.<br \/>\n    *   <code>[dragula]<\/code> direktifinin do\u011fru bir grup ad\u0131yla HTML elementine eklendi\u011finden emin olun.<br \/>\n    *   <code>dragula.min.css<\/code> dosyas\u0131n\u0131n <code>angular.json<\/code>&#8216;a veya ana stil dosyan\u0131za do\u011fru \u015fekilde import edildi\u011finden emin olun.<br \/>\n    *   Konsolda hata olup olmad\u0131\u011f\u0131n\u0131 kontrol edin.<br \/>\n*   <strong>CSS Stilleri Uygulanm\u0131yor:<\/strong><br \/>\n    *   <code>dragula.min.css<\/code>&#8216;in do\u011fru yoldan import edildi\u011finden emin olun. Yanl\u0131\u015f yol, stillerin y\u00fcklenmemesine neden olur.<br \/>\n    *   Kendi \u00f6zel stilleriniz, Dragula&#8217;n\u0131n varsay\u0131lan stillerini ge\u00e7ersiz k\u0131l\u0131yor olabilir. CSS \u00f6nceli\u011fini kontrol edin.<br \/>\n*   <strong><code>[(dragulaModel)]<\/code> Veriyi G\u00fcncellemiyor:<\/strong><br \/>\n    *   <code>dragulaModel<\/code> direktifini do\u011fru bir \u015fekilde iki y\u00f6nl\u00fc ba\u011flama (<code>[()]<\/code>) ile kulland\u0131\u011f\u0131n\u0131zdan emin olun.<br \/>\n    *   Veri modelinizin (\u00f6rne\u011fin <code>tasks<\/code> dizisi) do\u011fru bir \u015fekilde bile\u015feninizde tan\u0131mland\u0131\u011f\u0131ndan emin olun.<br \/>\n    *   E\u011fer karma\u015f\u0131k objeler kullan\u0131yorsan\u0131z, objelerin referanslar\u0131 yerine de\u011ferleri de\u011fi\u015fti\u011finde Angular&#8217;\u0131n de\u011fi\u015fiklik alg\u0131lamas\u0131n\u0131n tetiklenmesi i\u00e7in <code>dropModel<\/code> olay\u0131n\u0131 dinleyerek manuel olarak <code>ChangeDetectionRef.detectChanges()<\/code> \u00e7a\u011fr\u0131s\u0131 yapman\u0131z gerekebilir (ancak <code>ng2-dragula<\/code> genellikle bunu otomatik halleder).<br \/>\n*   <strong>Olaylar Tetiklenmiyor:<\/strong><br \/>\n    *   <code>DragulaService<\/code>&#8216;i bile\u015feninizin constructor&#8217;\u0131na do\u011fru \u015fekilde enjekte etti\u011finizden emin olun.<br \/>\n    *   Olaylara abone olurken do\u011fru grup ad\u0131n\u0131 kulland\u0131\u011f\u0131n\u0131zdan emin olun (<code>this.dragulaService.drop('my-bag').subscribe(...)<\/code>).<br \/>\n    *   Aboneliklerinizi <code>ngOnDestroy<\/code> i\u00e7inde temizlemeyi unutmay\u0131n (<code>this.subs.unsubscribe()<\/code>).<\/p>\n<h2>ng2-dragula Alternatifleri<\/h2>\n<p>Angular ekosisteminde s\u00fcr\u00fckle ve b\u0131rak i\u00e7in ba\u015fka se\u00e7enekler de bulunmaktad\u0131r:<\/p>\n<p>*   <strong><code>@angular\/cdk\/drag-drop<\/code>:<\/strong> Angular Component Dev Kit (CDK) b\u00fcnyesinde yer alan bu k\u00fct\u00fcphane, Angular&#8217;\u0131n resmi s\u00fcr\u00fckle ve b\u0131rak \u00e7\u00f6z\u00fcm\u00fcd\u00fcr. Tamamen Angular ile entegre, g\u00fc\u00e7l\u00fc ve esnektir. \u00d6zellikle Angular ekosistemine daha derinlemesine entegrasyon ve daha fazla kontrol arayanlar i\u00e7in iyi bir se\u00e7enektir. Ancak, kurulumu ve kullan\u0131m\u0131 <code>ng2-dragula<\/code>&#8216;ya g\u00f6re biraz daha karma\u015f\u0131k olabilir.<br \/>\n*   <strong><code>ngx-sortablejs<\/code>:<\/strong> SortableJS k\u00fct\u00fcphanesini Angular&#8217;a ta\u015f\u0131yan ba\u015fka bir pop\u00fcler \u00e7\u00f6z\u00fcmd\u00fcr. SortableJS, <code>dragula<\/code> gibi hafif ve esnek bir k\u00fct\u00fcphanedir. <code>ngx-sortablejs<\/code> de benzer bir kullan\u0131m kolayl\u0131\u011f\u0131 sunar.<\/p>\n<p><strong>Ne zaman <code>ng2-dragula<\/code>&#8216;y\u0131 se\u00e7melisiniz?<\/strong><br \/>\n*   H\u0131zl\u0131 ve basit bir s\u00fcr\u00fckle ve b\u0131rak \u00e7\u00f6z\u00fcm\u00fcne ihtiyac\u0131n\u0131z varsa.<br \/>\n*   <code>Dragula<\/code>&#8216;n\u0131n hafifli\u011fini ve minimal ba\u011f\u0131ml\u0131l\u0131klar\u0131n\u0131 tercih ediyorsan\u0131z.<br \/>\n*   Listeler aras\u0131nda veya i\u00e7inde \u00f6\u011fe s\u0131ralama ve ta\u015f\u0131ma gibi temel senaryolar i\u00e7in yeterli bir \u00e7\u00f6z\u00fcm ar\u0131yorsan\u0131z.<br \/>\n*   \u00d6zellikle karma\u015f\u0131k olmayan projelerde veya prototipleme a\u015famas\u0131nda h\u0131z kazanmak istiyorsan\u0131z.<\/p>\n<p><strong>Ne zaman <code>@angular\/cdk\/drag-drop<\/code>&#8216;\u0131 se\u00e7melisiniz?<\/strong><br \/>\n*   Angular ekosistemine daha derinlemesine entegre, resmi bir \u00e7\u00f6z\u00fcme ihtiyac\u0131n\u0131z varsa.<br \/>\n*   S\u00fcr\u00fckle ve b\u0131rak i\u015flemleri \u00fczerinde daha ince taneli kontrol (\u00f6rne\u011fin \u00f6zel yer tutucular, karma\u015f\u0131k k\u0131s\u0131tlamalar) gerekiyorsa.<br \/>\n*   Angular Material veya CDK&#8217;n\u0131n di\u011fer bile\u015fenleriyle birlikte kullan\u0131yorsan\u0131z.<br \/>\n*   Daha b\u00fcy\u00fck ve karma\u015f\u0131k projelerde uzun vadeli s\u00fcrd\u00fcr\u00fclebilirlik \u00f6nceli\u011finiz ise.<\/p>\n<p>Her iki k\u00fct\u00fcpherenin de kendine \u00f6zg\u00fc avantajlar\u0131 vard\u0131r ve se\u00e7im, projenizin \u00f6zel gereksinimlerine ve geli\u015ftirme ekibinin tercihine ba\u011fl\u0131d\u0131r.<\/p>\n<h2>Sonu\u00e7<\/h2>\n<p><code>ng2-dragula<\/code>, Angular uygulamalar\u0131n\u0131za s\u00fcr\u00fckle ve b\u0131rak i\u015flevselli\u011fi eklemek i\u00e7in g\u00fc\u00e7l\u00fc, esnek ve kullan\u0131m\u0131 kolay bir \u00e7\u00f6z\u00fcmd\u00fcr. Basit kurulumu, <code>[(dragulaModel)]<\/code> ile veri modeline do\u011frudan entegrasyonu ve zengin olay\/se\u00e7enek API&#8217;si sayesinde, hem temel liste s\u0131ralamalar\u0131ndan hem de karma\u015f\u0131k Kanban panosu benzeri aray\u00fczlere kadar geni\u015f bir yelpazede s\u00fcr\u00fckle ve b\u0131rak ihtiya\u00e7lar\u0131n\u0131z\u0131 kar\u015f\u0131layabilir.<\/p>\n<p>Bu makalede ele ald\u0131\u011f\u0131m\u0131z ad\u0131mlar\u0131 ve \u00f6rnekleri takip ederek, Angular uygulamalar\u0131n\u0131z\u0131n kullan\u0131c\u0131 deneyimini <code>ng2-dragula<\/code> ile \u00f6nemli \u00f6l\u00e7\u00fcde zenginle\u015ftirebilirsiniz. Unutmay\u0131n, kullan\u0131c\u0131 dostu aray\u00fczler, uygulaman\u0131z\u0131n ba\u015far\u0131s\u0131 i\u00e7in kritik \u00f6neme sahiptir ve s\u00fcr\u00fckle ve b\u0131rak, bu hedefe ula\u015fman\u0131za yard\u0131mc\u0131 olabilecek g\u00fc\u00e7l\u00fc bir ara\u00e7t\u0131r. Projenizin ihtiya\u00e7lar\u0131na g\u00f6re <code>ng2-dragula<\/code>&#8216;n\u0131n sundu\u011fu esnekli\u011fi kullanarak, \u00f6zelle\u015ftirilmi\u015f ve etkile\u015fimli kullan\u0131c\u0131 aray\u00fczleri olu\u015fturmaktan \u00e7ekinmeyin.<\/body><\/p>\n","protected":false},"excerpt":{"rendered":"Angular Uygulamalar\u0131n\u0131zda ng2-dragula ile S\u00fcr\u00fckle ve B\u0131rak \u00d6zelli\u011fi\nModern web uygulamalar\u0131nda kullan\u0131c\u0131 deneyimi (UX), ba\u015far\u0131n\u0131n anahta","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"csco_page_header_type":"","csco_page_load_nextpost":"","csco_page_subscribe_form":"","csco_page_contact_form":"","footnotes":""},"categories":[1488],"tags":[],"class_list":{"0":"post-30364","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-angular","7":"cs-entry","8":"cs-video-wrap"},"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.5 (Yoast SEO v25.3.1) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Angular Uygulamalar\u0131n\u0131zda ng2-dragula ile S\u00fcr\u00fckle ve B\u0131rak \u00d6zelli\u011fi - Kodlar\u0131n Gizemli D\u00fcnyas\u0131<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/fatihsoysal.com\/blog\/angular-uygulamalarinizda-ng2-dragula-ile-surukle-ve-birak-ozelligi\/\" \/>\n<meta property=\"og:locale\" content=\"tr_TR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Angular Uygulamalar\u0131n\u0131zda ng2-dragula ile S\u00fcr\u00fckle ve B\u0131rak \u00d6zelli\u011fi\" \/>\n<meta property=\"og:description\" content=\"Angular Uygulamalar\u0131n\u0131zda ng2-dragula ile S\u00fcr\u00fckle ve B\u0131rak \u00d6zelli\u011fi Modern web uygulamalar\u0131nda kullan\u0131c\u0131 deneyimi (UX), ba\u015far\u0131n\u0131n anahta\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fatihsoysal.com\/blog\/angular-uygulamalarinizda-ng2-dragula-ile-surukle-ve-birak-ozelligi\/\" \/>\n<meta property=\"og:site_name\" content=\"Kodlar\u0131n Gizemli D\u00fcnyas\u0131\" \/>\n<meta property=\"article:published_time\" content=\"2025-09-26T20:41:24+00:00\" \/>\n<meta name=\"author\" content=\"Fatih Soysal\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Yazan:\" \/>\n\t<meta name=\"twitter:data1\" content=\"Fatih Soysal\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tahmini okuma s\u00fcresi\" \/>\n\t<meta name=\"twitter:data2\" content=\"25 dakika\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/angular-uygulamalarinizda-ng2-dragula-ile-surukle-ve-birak-ozelligi\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/angular-uygulamalarinizda-ng2-dragula-ile-surukle-ve-birak-ozelligi\/\"},\"author\":{\"name\":\"Fatih Soysal\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"headline\":\"Angular Uygulamalar\u0131n\u0131zda ng2-dragula ile S\u00fcr\u00fckle ve B\u0131rak \u00d6zelli\u011fi\",\"datePublished\":\"2025-09-26T20:41:24+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/angular-uygulamalarinizda-ng2-dragula-ile-surukle-ve-birak-ozelligi\/\"},\"wordCount\":3319,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"articleSection\":[\"Angular\"],\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/angular-uygulamalarinizda-ng2-dragula-ile-surukle-ve-birak-ozelligi\/#respond\"]}],\"copyrightYear\":\"2025\",\"copyrightHolder\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/angular-uygulamalarinizda-ng2-dragula-ile-surukle-ve-birak-ozelligi\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/angular-uygulamalarinizda-ng2-dragula-ile-surukle-ve-birak-ozelligi\/\",\"name\":\"Angular Uygulamalar\u0131n\u0131zda ng2-dragula ile S\u00fcr\u00fckle ve B\u0131rak \u00d6zelli\u011fi - Kodlar\u0131n Gizemli D\u00fcnyas\u0131\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\"},\"datePublished\":\"2025-09-26T20:41:24+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/angular-uygulamalarinizda-ng2-dragula-ile-surukle-ve-birak-ozelligi\/#breadcrumb\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/angular-uygulamalarinizda-ng2-dragula-ile-surukle-ve-birak-ozelligi\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/angular-uygulamalarinizda-ng2-dragula-ile-surukle-ve-birak-ozelligi\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Anasayfa\",\"item\":\"https:\/\/fatihsoysal.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Angular Uygulamalar\u0131n\u0131zda ng2-dragula ile S\u00fcr\u00fckle ve B\u0131rak \u00d6zelli\u011fi\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/\",\"name\":\"Fatihsoysal.com\",\"description\":\"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim\",\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"tr\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\",\"name\":\"Fatih Soysal\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"tr\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"contentUrl\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"width\":512,\"height\":512,\"caption\":\"Fatih Soysal\"},\"logo\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\"},\"description\":\"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Angular Uygulamalar\u0131n\u0131zda ng2-dragula ile S\u00fcr\u00fckle ve B\u0131rak \u00d6zelli\u011fi - Kodlar\u0131n Gizemli D\u00fcnyas\u0131","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/fatihsoysal.com\/blog\/angular-uygulamalarinizda-ng2-dragula-ile-surukle-ve-birak-ozelligi\/","og_locale":"tr_TR","og_type":"article","og_title":"Angular Uygulamalar\u0131n\u0131zda ng2-dragula ile S\u00fcr\u00fckle ve B\u0131rak \u00d6zelli\u011fi","og_description":"Angular Uygulamalar\u0131n\u0131zda ng2-dragula ile S\u00fcr\u00fckle ve B\u0131rak \u00d6zelli\u011fi Modern web uygulamalar\u0131nda kullan\u0131c\u0131 deneyimi (UX), ba\u015far\u0131n\u0131n anahta","og_url":"https:\/\/fatihsoysal.com\/blog\/angular-uygulamalarinizda-ng2-dragula-ile-surukle-ve-birak-ozelligi\/","og_site_name":"Kodlar\u0131n Gizemli D\u00fcnyas\u0131","article_published_time":"2025-09-26T20:41:24+00:00","author":"Fatih Soysal","twitter_card":"summary_large_image","twitter_misc":{"Yazan:":"Fatih Soysal","Tahmini okuma s\u00fcresi":"25 dakika"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/fatihsoysal.com\/blog\/angular-uygulamalarinizda-ng2-dragula-ile-surukle-ve-birak-ozelligi\/#article","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/angular-uygulamalarinizda-ng2-dragula-ile-surukle-ve-birak-ozelligi\/"},"author":{"name":"Fatih Soysal","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"headline":"Angular Uygulamalar\u0131n\u0131zda ng2-dragula ile S\u00fcr\u00fckle ve B\u0131rak \u00d6zelli\u011fi","datePublished":"2025-09-26T20:41:24+00:00","mainEntityOfPage":{"@id":"https:\/\/fatihsoysal.com\/blog\/angular-uygulamalarinizda-ng2-dragula-ile-surukle-ve-birak-ozelligi\/"},"wordCount":3319,"commentCount":0,"publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"articleSection":["Angular"],"inLanguage":"tr","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/fatihsoysal.com\/blog\/angular-uygulamalarinizda-ng2-dragula-ile-surukle-ve-birak-ozelligi\/#respond"]}],"copyrightYear":"2025","copyrightHolder":{"@id":"https:\/\/fatihsoysal.com\/blog\/#organization"}},{"@type":"WebPage","@id":"https:\/\/fatihsoysal.com\/blog\/angular-uygulamalarinizda-ng2-dragula-ile-surukle-ve-birak-ozelligi\/","url":"https:\/\/fatihsoysal.com\/blog\/angular-uygulamalarinizda-ng2-dragula-ile-surukle-ve-birak-ozelligi\/","name":"Angular Uygulamalar\u0131n\u0131zda ng2-dragula ile S\u00fcr\u00fckle ve B\u0131rak \u00d6zelli\u011fi - Kodlar\u0131n Gizemli D\u00fcnyas\u0131","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/#website"},"datePublished":"2025-09-26T20:41:24+00:00","breadcrumb":{"@id":"https:\/\/fatihsoysal.com\/blog\/angular-uygulamalarinizda-ng2-dragula-ile-surukle-ve-birak-ozelligi\/#breadcrumb"},"inLanguage":"tr","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fatihsoysal.com\/blog\/angular-uygulamalarinizda-ng2-dragula-ile-surukle-ve-birak-ozelligi\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/fatihsoysal.com\/blog\/angular-uygulamalarinizda-ng2-dragula-ile-surukle-ve-birak-ozelligi\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Anasayfa","item":"https:\/\/fatihsoysal.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Angular Uygulamalar\u0131n\u0131zda ng2-dragula ile S\u00fcr\u00fckle ve B\u0131rak \u00d6zelli\u011fi"}]},{"@type":"WebSite","@id":"https:\/\/fatihsoysal.com\/blog\/#website","url":"https:\/\/fatihsoysal.com\/blog\/","name":"Fatihsoysal.com","description":"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim","publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"tr"},{"@type":["Person","Organization"],"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1","name":"Fatih Soysal","image":{"@type":"ImageObject","inLanguage":"tr","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","contentUrl":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","width":512,"height":512,"caption":"Fatih Soysal"},"logo":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/"},"description":"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.","url":"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/"}]}},"yoast_meta":{"yoast_wpseo_title":"","yoast_wpseo_metadesc":"","yoast_wpseo_canonical":""},"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/30364","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/comments?post=30364"}],"version-history":[{"count":1,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/30364\/revisions"}],"predecessor-version":[{"id":30365,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/30364\/revisions\/30365"}],"wp:attachment":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/media?parent=30364"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/categories?post=30364"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/tags?post=30364"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}