Let's see what Abstract can do.
Rendering
var header = new RenderModel({ el: "#render", data: { title: "Abstract.js", desc: "Abstract.js is next framework for the web" }, tmpl: "{{title}}<br />{{desc}}" }); header.rock();
Listing
Try scrolling to bottom
var listing = new ScrollModel({ data: { list: [ 'Abstact.js publishes version 2.0', 'Abstact.js publishes version 2.0', 'Abstact.js publishes version 2.0', 'Abstact.js publishes version 2.0', 'Abstact.js publishes version 2.0' ] }, scrollEl: '#listing', tmpl: "<li soda-repeat='item in list'>{{item}}</li>", el: "#listing" }); listing.rock();
载入中
Tabs
var tab1 = new RenderModel({ el: ".tabpage", data: { name: "tab1" }, tmpl: "{{name}}" }); var tab2 = tab1.extend({ data: { name: "tab2" } }); var tab3 = tab1.extend({ data: { name: "tab3" } }); // Telling The Relationship Between Models var tab = new MultitabModel(); tab.add(".tab1", tab1); tab.add(".tab2", tab2); tab.add(".tab3", tab3); tab.rock();
- tab1
- tab2
- tab3
Paging
var pageList = new RenderModel({ el: ".contentList", tmpl: "<li soda-repeat='item in list'>{{item}}</li>", data: { list: [ "第1页数据" ] }, processData: function(){ } }); var pagation = new RenderModel({ el: ".pagation", tmpl: "<li data-index='{{$index + 1}}' class='pageItem' soda-repeat='item in list'>{{$index + 1}}</li>", data: { list: new Array(10) }, processData: function(){ }, events: function(){ var els = document.querySelectorAll(".pageItem"); for(var i = 0; i < els.length; i ++){ var el = els[i]; el.onclick = function(){ var index = this.getAttribute("data-index"); pageList.data = { list: [ ] }; for(var j = 0; j < index; j ++){ pageList.data.list.push("第" + (index) + "页数据"); } pageList.refresh(); }; } } }); // Telling The Relationship Between Models var pageWrapper = new PageModel(); pageWrapper.add(pageList); pageWrapper.add(pagation); pageWrapper.rock();
Quick Mobile Page
var header = new RenderModel({ el: "#header", data: { name: "Header" }, tmpl: "{{name}}" }); var newsList = new ScrollModel({ data: { list: [ 'Abstact.js publishes version 2.0', 'Abstact.js publishes version 2.0', 'Abstact.js publishes version 2.0', 'Abstact.js publishes version 2.0', 'Abstact.js publishes version 2.0' ] }, scrollEl: '.subpage1', tmpl: "<li soda-repeat='item in list'>{{item}}</li>", el: ".subpage1 ol" }); var newsTab = new PageModel(); var newsFrame = new RenderModel({ tmpl: "<ol></ol><div>加载中</div>", el: ".subpage1", onreset: function(){ document.querySelector(".subpage1").innerHTML = ""; } }); newsTab.add(newsFrame); newsTab.add(newsList); var me = new RenderModel({ tmpl: "Me Tab", el: ".subpage2" }); var setting = me.extend({ tmpl: "Setting Tab", el: ".subpage3" }); // Telling The Relationship Between Models var tabs = new MultitabModel(); tabs.add(".news", newsTab); tabs.add(".me", me); tabs.add(".setting", setting); var page = new PageModel(); page.add(header); page.add(tabs); page.rock();
- news
- me
- settings
Higher Level Usage
Dialog
// dialog var dialogRender = new RenderModel({ data: { title: "Dialog", content: "Abstact publishes Version 2.0" }, fuse: Model.createFuse("click", "#showDialog"), el: ".dialogWrapper", tmpl: "<h2>{{title}}<span class='close'>close</span></h2>&tl;div class='dialogContent'>{{content}}</div>" }); dialogRender.addEventListener("beforeactived", function(){ document.querySelector(".dialogWrapper").innerHTML = ""; this.show(); }); dialogRender.addEventListener("unactived", function(){ this.hide(); }); var closeModel = new BaseModel({ fuse: Model.createFuse("click", ".close") }); // Telling The Relationship Between Models var controller = new MutexModel(); controller.add(closeModel); controller.add(dialogRender); controller.rock();
Show Dialog
Dialog(Using MultitabModel, less code)
// dialog var dialogRender2 = new RenderModel({ data: { title: "Dialog", content: "Abstact publishes Version 2.0" }, el: ".dialogWrapper2", tmpl: "<h2>{{title}}<span class='close2'>close</span></h2><div class='dialogContent'>{{content}}</div>" }); var closeModel2 = new BaseModel({ }); // Telling The Relationship Between Models var controller2 = new MultitabModel(); controller2.add(".close2", closeModel2); controller2.add("#showDialog2", dialogRender2); controller2.rock();
Show Dialog
MultiPage with Animation
var page1 = new PageModel(); var pageContent = new RenderModel({ tmpl: "page1 <br /><br /><div class='btn openPage2'>open page2</div>", el: ".subpage_1" }); page1.add(pageContent); pageContent.hide = function(){ Model.$(this.el).removeClass("current"); }; pageContent.show = function(){ Model.$(this.el).addClass("current"); }; var page2 = page1.extend(); page2.children[0].tmpl = "page2 <br /><br /><span class='btn closePage2'>back</span>"; page2.children[0].el = ".subpage_2"; // Telling The Relationship Between Models var controllPage = new MultitabModel(); controllPage.add(".closePage2", page1); controllPage.add(".openPage2", page2); controllPage.rock();
Pic Slider
The pic comes in the same direction; Just less than 50 lines code to write an perfect pic slider with clear logic without event bindings;
var picsRender1 = new RenderModel({ data: { src: "girl", }, tmpl: "<img soda-src='image/{{src}}.jpg' />", el: ".pics_1" }); picsRender1.show = function(){ Model.$(this.el).addClass("waiting"); var _this = this; setTimeout(function(){ Model.$(_this.el).removeClass("waiting"); Model.$(_this.el).addClass("showAni"); }, 0); }; picsRender1.hide = function(){ Model.$(this.el).removeClass("showAni"); }; var picsRender2 = picsRender1.extend({ data: { src: "car" }, el: ".pics_2" }); var picsRender3 = picsRender1.extend({ data: { src: "dog" }, el: ".pics_3" }); var controllTab = new MultitabModel(); controllTab.add(".controll1", picsRender1); controllTab.add(".controll2", picsRender2); controllTab.add(".controll3", picsRender3); controllTab.rock();
MVVM Using
Abstract is not MVVM Framework, but also Abstract can construct MVVM logics as well.
But Abstract concerns about the logic about datas, not the views.
But Abstract concerns about the logic about datas, not the views.
To Do
var todoList = new RenderModel({ data: { list: [] }, el: ".toList", tmpl: "<ul><li soda-repeat='item in list'>{{item}}</li></ul>", events: function(){ var input = document.getElementById("toDoInput"); var button = document.getElementById("add"); var _this = this; add.onclick = function(){ var text = input.value; _this.data.list = _this.data.list.concat(text); input.value = ""; _this.refresh(); }; } }); todoList.rock();
To Do
Markdown Editor
var markdown = new RenderModel({ el: ".outMd", data: { content: "" }, events: function(){ var textarea = document.querySelector("#mdInput"); var _this = this; textarea.addEventListener("input", function(e){ _this.data.content = marked(this.value, {sanitize: true}); _this.refresh(); }); }, tmpl: "<span soda-bind-html='content'></span>" }); markdown.rock();
Input
Output
Progress Bar
var bar = new RenderModel({ el: "#bar", data: { width: 0 }, tmpl: "<div style='width: {{width}}%'></div>", events: function(){ var _this = this; setInterval(function(){ _this.data.width += 0.3; if(_this.data.width > 100){ _this.data.width = 0; } _this.refresh(); }, 1000 / 60); } }); bar.rock();