Önceki yazıda aşağıdaki uygulamayı Nginx+Tornado Server ile sunmak için kullandığım dosyaları paylaşmıştım. Daha önce de basit bir panele bir açılır düğme yerleştirmiştim. Şimdi işi biraz büyütüp MVC havası katıyorum ve bir form oluşturuyorum.
Özellikle baseUrl: tanımlamasına ve yollar için app/ kullanıldığına dikkat edin.
main.coffee
require { baseUrl : "/static/app" }, [ "dojo/dom", "app/mainPanel" ], ( dom) -> #Bir panel oluşturuyoruz panel = new app.mainPanel() #Panelin DOM yapısını köke yani HTML BODY'e ekliyoruz dojo.body().appendChild(panel.domNode) #Tarayıcılar standart HTM özelliklerine göre yerleşimi yaptı #Ama Dojo nesneleri yerleşimler için özel değişkenler kullanıyor #Herşey hazır olduğunda, dojo'nun kendi özelliklerine uygun yerleşimi yapmasını istiyoruz panel.startup()
mainPanel.coffee
define \ ["dojo/_base/declare", "app/mainPanel_ui", "dojo/domReady!"], (declare) -> #declare İfadesini Python ve C++'deki Class gibi düşünebilirsiniz, bir tür sınıf oluşturuyoruz, bir prototip #declare İfadesi ile tanımlanan yapılar global olarak erişilebilir oluyor #app.mainPanel_ui Sınıfından miras alıyoruz declare "app.mainPanel", [app.mainPanel_ui],
mainPanel_ui.coffee
define \ ["dojo/_base/declare", "dijit/_WidgetBase", "dijit/layout/BorderContainer", "dijit/layout/ContentPane", "app/userModule", "dojo/domReady!"], (declare, _WidgetBase, BorderContainer, ContentPane) -> #Global erişim için app.mainPanel_ui kullanılacak, BorderContainer'den miras alıyoruz #böylece nesnemiz bir BorderContainer kopyası oluyor #Miras alınanlar ve bu sınıfa ait değişkenlere this nesnesi ile erişilebiliyor declare "app.mainPanel_ui", [BorderContainer], #Yapıcı fonksiyon kullanılabilir constructor: () -> this.design = "headline" this.baseClass = ".dijitReset" this.style = "overflow:hidden; color:white; border: 0; background-color:#333333; width: 100%; height: 32px; " #Menüyü tanımlıyoruz this.menuContainer = new ContentPane(region:"center", style: "overflow:hidden; ", \ content:"menü1 | menü2 | menü3 | menü4") #Kullanıcı işlemlerini yapacak modülü tanımlıyoruz this.user = new app.userModule() #DOM Nesneler oluşturulduktan sonra tanımladığımız nesneleri DOM'a ekleyebiliriz postCreate:() -> this.addChild(this.menuContainer) this.addChild(this.user)
Uygulamanın bölümlerini kullanıcı arayüzünü oluşturacak ve işlevleri yürütecek iki ayrı yapı olarak tanımlayıp görsel arayüzü işlev yapısına miras alınan nesne olarak bağlıyorum. Olayları da /dojo/on işlevi ile bağlıyorum.
userModule.coffee
define \ ["dojo/_base/declare", "dojo/on", "app/userModule_ui", "dojo/domReady!"], (declare,event) -> declare "app.userModule", [app.userModule_ui], constructor: () -> #dojo/on İşlevi ile nesne olaylarını işlevlere bağlayabiliyoruz event(this.login_button, "click", this.onButtonClick) event(this.login_pass_lost, "click", this.onPassLostClick) onButtonClick: (evt) -> #Sunucuya bağlanıp kimlik kontrolü yapılacak console.log("login") onPassLostClick: (evt) -> #stack nesnesinin lostContent içeriği gösterilecek console.log("lost")
Kodu uzatmamak için sadece kullanıcı girişi formu oluşturdum.
userModule_ui.coffee
define \ ["dojo/_base/declare", "dojo/on", "dojo/dom-construct", "dijit/form/DropDownButton", "dijit/TooltipDialog", "dijit/layout/StackContainer", "dijit/layout/StackController", "dijit/layout/ContentPane", "dijit/form/TextBox", "dijit/form/Form", "dijit/form/Button", "dijit/form/CheckBox", "dijit/layout/BorderContainer", "dojox/layout/TableContainer", "dojo/dom-geometry"], (declare, event, domConstruct, DropDownButton, TooltipDialog, StackContainer, StackController, ContentPane, \ TextBox, Form, Button, CheckBox, BorderContainer,TableContainer, domGeometry) -> declare "app.userModule_ui", [ContentPane], constructor: () -> this.region = "right" this.style = "overflow:hidden" #Kullanıcı girişi this.login_form = new Form() this.login_container = new TableContainer(cols:1, labelWidth:"100%") this.login_uname = new TextBox(label:"Kullanıcı Adı :") this.login_pass = new TextBox(label:"Parola :",type:"password") this.login_uname_save = new CheckBox(label:"Beni hatırla: ") this.login_button = new Button( label:"Oturum Açma") this.login_pass_lost = new ContentPane( content:dojo.create("span", style:"cursor:pointer;", innerHTML:"Parolamı unttum") ) this.login_container.addChild(this.login_uname) this.login_container.addChild(this.login_pass) this.login_container.addChild(this.login_uname_save) #Button'u ContentPane içine almazsak etiketi ayrıca yanında gösterecektir this.login_container.addChild(new ContentPane( content:this.login_button)) this.login_container.addChild( this.login_pass_lost ) this.login_form.domNode.appendChild(this.login_container.domNode) this.loginContent = new ContentPane( content:this.login_form) #Kayıp parola this.lostContent = new ContentPane( content:"Lost password") #Yeni kullanıcı kaydı this.registerContent = new ContentPane( content:"Register Form") #Kullanıcı bilgileri this.userContent = new ContentPane( content:"User account") #Taşıyıcı, düğme ve açılan diyalog this.stack = new StackContainer(style: "height: 200px; width: 400px;") this.userDialog = new TooltipDialog( content:this.stack) this.userButton = new DropDownButton(label:"Giriş yapın", baseClass:".dijitReset", dropDown:this.userDialog) this.content = this.userButton postCreate:() -> this.stack.addChild(this.loginContent) this.stack.addChild(this.lostContent) this.stack.addChild(this.registerContent) this.stack.addChild(this.userContent)
Çalıştırınca şöyle bir görüntü veriyor.
Ancak JS'in bir saçmalığı mı bilemiyorum olay bağladığım işlevlerde this nesnesi daima olayı oluşturan nesne oluyor, örneğin onButtonClick işlevi içerisinde this. nesnesi app.userMoudule olacağına login_button oluyor. Yani "object scope" konusunda bir saçmalık var, şükür ki Dojo ile bunun çaresi de var, onu da bir sonraki yazıya.
Hiç yorum yok:
Yorum Gönder