這禮拜就是2012 SimpleLife 簡單生活節
整個華山同時有四個舞台的音樂演出
前兩屆 每次去總覺得要一直翻紙本的節目表
有點麻煩
在公司用mobile web做了簡易的手機版演出節目表
使用了AppCache 只要開啟過,離線也可正常使用
start |
home |
可以查詢兩日各舞台的演出節目 |
可即時查詢各舞台正在進行的演出 |
簡易的歌手介紹 |
http://simplelife.streetvoice.com/m/ |
start |
home |
可以查詢兩日各舞台的演出節目 |
可即時查詢各舞台正在進行的演出 |
簡易的歌手介紹 |
http://simplelife.streetvoice.com/m/ |
ssh-keygen -C "youremail@xxx"
預設會儲存為id_rsa 的key,不同的email產生key請設定使用不同檔名儲存Host PeterBitbucket
HostName bitbucket.org
User git
IdentityFile ~/.ssh/peter_id_rsa
IdentitiesOnly yes
Host OzzyBitbucket
HostName bitbucket.org
User git
IdentityFile ~/.ssh/ozzy_id_rsa
IdentitiesOnly yes
git remote add git@bitbucket.org:ozzy/myrepos.git
改用以下方式設定git remote add OzzyBitbucket:ozzy/myrepos.git
另一個帳號git remote add PeterBitbucket:peter/myrepos.git
讓不同的帳號使用不同的ssh key連線
sudo apt-get install git
git init
git status
git log
git add filename
全部有異動的都加入git add .
git rm filename
刪除目錄git rm -rf dirname
git reset HEAD filename
git commit -m "xxx"
git reset -hard HEAD~1
數字代表回復到前幾個版本git clone 遠端目錄
git remote add aliasName remote路徑
git remote -v
git pull origin master
git push origin maste
git stash
git pull origin master
git stash apply
把自己放在暫存區已改過的檔案與最新拉回來的檔案merge在一起,git add .
git commit -m xxxx
git push origin master
git init --bare
該目錄即可成為一個git remote
file:myclass.coffee
class MyClass
constructor:(@name)->
module.exports=MyClass
2.使用Rocker=require('./myclass')
rocker=new Rocker()
file:myclass.coffee
class MyClass
constructor:(@name)->
class MyClass2
exports.Rocker=MyClass
exports.Tester=MyClass2
2.使用MyRocker= require('./myclass').Rocker
MyTester= require('./myclass').Tester
rocker=new MyRocker('oz')
AddType text/cache-manifest .manifest
<html manifest='cache.manifest'>
在所有會成為進入點的網頁,都需要加入設定指向manifest檔案CACHE MANIFEST 必要的第一行
CACHE:
區塊設定要cache的檔案清單
NETWORK:
區塊設定一定要由網路讀取的清單
FALLBACK:
區塊設定當讀取失敗,要轉向使用哪個替代內容顯示
例CACHE MANIFEST
#ver 0.0.1
CACHE:
index.htm
/js/main.min.js
/css/app.css
/img/btn_img.png
NETWORK:
*
FALLBACK:
<script scr="xx.js?ver=1.0"></script>
使用Application Cache請不要再使用這樣的手法,把Cache的管理都交給manifest處理即可html:[
"this html block..........",
"kkman"
].join('')
2.HTMLElementhtml:[
"<div>this html block..........</div>",
"<hr/>",
"<div>hello</div>"
].join('')
3.Ext.Element ?? tpl:"<div><div>Hello me</div><div>{name}</div><div>{rock}</div></div>"
tpl:[
"<div>",
"<div>Hello me</div>",
"<div>{name}</div>",
"<div>{rock}</div>",
"</div>"
].join('')
3.Ext.Template[]tpl:new Ext.Template("<div>Hello {name}.</div>")
例 在initial程序中使用this.setTpl(new Ext.Template("<div>Hello me {name}.</div>"))
this.setData([
{
name:'ozzy',
type:'metal'
},
{
name:'linda',
type:'Rock'
}
]);
在config內設定tpl:new Ext.XTemplate(
'<tpl for=".">',
'<p>{name}</p>',
'<p>{type}</p>',
'<hr>',
'</tpl>'
)
三.itemTplitemTpl:'<p> {name}</p><p> {type}</p>'
2.String[]itemTpl:[
'<p>{name}</p>',
'<p>{type}</p>',
'<hr>'
].join('')
3.Ext.XTemplateitemTpl:new Ext.XTemplate(
'<p>{name}</p>',
'<p>{type}</p>',
'<hr>'
)
4.使用setData var list={
xtype:'list',
itemId:'mylist',
itemTpl:new Ext.XTemplate(
'<p>{name}</p>',
'<p>{type}</p>',
'<hr>'
)
}
this.getComponent('mylist').setData([
{
name:'ozzy',
type:'metal'
},
{
name:'linda',
type:'Rock'
}
]);
Ext.define('User', {
extend: 'Ext.data.Model',
config: {
fields: [
{name: 'id', type: 'int'},
{name: 'name', type: 'string'},
{name: 'obj', type: 'auto'},
]
}
});
Ext.define('User', {
extend: 'Ext.data.Model',
config: {
fields: [
{name: 'id', type: 'int'},
{name: 'name', type: 'string'},
{name: 'obj', type: 'auto'},
],
validations: [
{ type: 'presence', field: 'id' },
{ type: 'presence', field: 'name', message: '不可空白'}
]
}
});
Ext.define('User', {
extend: 'Ext.data.Model',
config: {
fields: [
{name: 'id', type: 'int'},
{name: 'name', type: 'string'}
],
hasMany: {model: 'Product', name: 'products'}
}
});
代表User內有一個products屬性,這個屬性內儲存著Product Model的ArrayUser.load(1, {
success: function(user) {
console.log("User: " + user.get('name'));
user.posts().each(function(post) {
console.log(post.get('title'));//post本身即是一個model
post.comments().each(function(comment) {//post內的comment也是一個model
console.log(comment.get('message'));
});
});
}
});
3.當model有設定belongTo,就可以取得其上層model instanceExt.define('User', {
extend: 'Ext.data.Model',
config: {
fields: [
{name: 'id', type: 'int'},
{name: 'name', type: 'string'}
],
hasMany: {model: 'Post', name: 'prosts'}
}
});
Ext.define('Post', {
extend: 'Ext.data.Model',
config: {
fields: [
{name: 'id', type: 'int'},
{name: 'name', type: 'string'}
],
belongsTo: 'User'
}
});
post.getUser(function(user) {//非同步,要透過callback取得user
console.log('post: ' + user.get('name'))
});
Ext.define("Stest.model.ItemModel", {
extend: "Ext.data.Model",
config: {
idProperty: 'firstName',
fields: [
{ name: 'firstName', type: 'string' },
{ name: 'lastName', type: 'string'}
]
}
});
注意:當作localStorage Store使用的model,不可使用id field,必須由系統產生Ext.define("Stest.model.ItemModel", {
extend: "Ext.data.Model",
config: {
idProperty: 'firstName',
fields: [
{ name: 'firstName', type: 'string' },
{ name: 'lastName', type: 'string'}
]
}
});
{
meta:{},
users:[
{},{}...
]
}
Ext.define("My.store.MyStore", {
extend: "Ext.data.Store",
config: {
model: "My.model.UserModel",
proxy: {
type: 'ajax',
reader: {
type: 'json'
}
},
rootProperty:"users"
}
});
Ext.define("My.store.MyStore", {
extend: "Ext.data.Store",
config: {
model: "My.model.UserModel",
proxy: {
type: 'ajax',
reader: {
type: 'json'
}
}
}
listeners:{
load:function(store,records,_success,operation,opts){
for(var i=0;i
records[i].set('uid',records[i].get('id'));
delete records[i].getData().id;
}
}
}
});
Ext.define("My.store.MyStore", {
extend: "Ext.data.Store",
config: {
model: "My.model.MyModel",
proxy: {
type: 'ajax',
reader: {
type: 'json',
rootProperty:function(data){
return data.users
}
}
},
listeners:{
load:function(store,records,_success,operation,opts){
for(var i=0;i
records[i].set('uid',records[i].get('id'));
delete records[i].getData().id;
}
//---兩種方式都可以----
store.each(function(record, index){
record.set('index', index);
},store)
}
}
}
});
listeners:{
load:function(store,records,_success,operation,opts){
var _objs=[];
for(var i=0;i
records[i].set('uid',records[i].get('id'));
delete records[i].getData().id;
_objs.push(records[i].getData())
}
var anotherStore=Ext.getStore('AnotherStore');
localStore.add(_objs);
}
}
Ext.create('Ext.data.Store', {
model: 'SomeModel',
storeId: 'myStore'
});
var store = Ext.data.StoreManager.lookup('myStore');
2.modelExt.define("MyApp.store.MyStore", {
extend: "Ext.data.Store",
config: {
model: "MyApp.model.ItemModel",
proxy: {
type: 'ajax',
reader: {
type: 'json',
rootProperty: function(data) {
...
return data;
}
}
},
clearOnPageLoad:true,
listeners:{
load:function(store,records,_success,operation,opts){
.....
}
}
}
});
三.Store功能sorters: [{
property: 'artist',
direction: 'DESC'
}]
DESC:由大到小
ASC:由小到大
filters: [{
property: 'name',
value : 'Ed'
}]
3.groupField,groupDir,grouperExt.create('Ext.data.Store', {
model: 'User',
sorters: ['name', 'id'],//取得的資料會以name,id依序排列
filters: {
property: 'name',//只有欄位name值=Ed的資料才會取出來
value : 'Ed'
},
groupField: 'age',//以age欄位來group資料,
groupDir: 'DESC'//用由大往小方式排列
});
四.Store載入資料var store = Ext.create('Ext.data.Store', {
autoLoad: true,
model: 'User',
data : data,
proxy: {
type: 'memory',
reader: {
type: 'json',
root: 'users'
}
}
});
2.load(options,scope)載入資料 store.load({
callback:function(records, operation, success){}
})
store.getAt(index)
3.使用指定欄位值找modelstore.findRecord(fieldName,value)
4.注意store.getData().length(取得目前資料數量)
或store.getCount()
5.使用在callback內取得的資料var _url="server/proxy.php?type=song&songid="+id;
Ext.getStore("SongFileStore").getProxy().setUrl(_url);
Ext.getStore("SongFileStore").load({
callback: function(records, operation, success) {
console.log(records[0].data.url);
},
scope: this
});
var list={
xtype:'itemList',
itemId:'list',
store:Ext.getStore('GroupItemsStore'),
listeners:{
itemsingletap:{
fn:this.onClickItem,
scope:this
}
}
}
Ext.getStore("SongCardStore").load({
callback: function(records, operation, success) {
//console.log('load song card compllete='+)
console.log('this');
console.log(this);
},
scope: Ext.getStore("SongCardStore")
});
Ext.define("Test.model.ItemModel", {
extend: "Ext.data.Model",
config: {
fields: [
{ name: 'uid', type: 'string' },
{ name: 'fName', type: 'string' },
{ name: 'lName', type: 'string'}
]
}
});
Ext.define("Test.store.ItemStore", {
extend: "Ext.data.Store",
requires:['Ext.data.proxy.LocalStorage'],
config: {
model: "Test.model.ItemModel",
storeId:'hahaha',
proxy: {
type: 'localstorage',
id : 'mylocal'
}
}
});
四.儲存store.add([{..},{...}]) 加入資料
store.sync() 寫到localStorage上
store.load()
若原本store內有資料,但localStorage內是空的,store.removeAll();
2.清除localStorage資料store.getProxy().clear()
chmod +x SenchaSDKTools-2.0.0-beta3.run
4.執行安裝sudo ./SenchaSDKTools-2.0.0-beta3.run
5.加入環境變數sudo gedit .bashrc
加入PATH='/opt/SenchaSDKTools-2.0.0-beta3'
sencha app create 專案nameSpace ../專案目錄名稱
例app:所有要開發的程式都放在這裡
sdk:sencha touch 使用的sdk
resource:專案使用的css與圖檔放在這裡
app.json:架構上使用microloader,在這檔案設定要使用的css,js等相關路徑設定
與專案輸出的設定
app.js:App程式進入點
packager.js:這是要將整個project package成App時的設定檔
4.app.json設定檔"js": [
{
"path": "sdk/sencha-touch.js"
},
{
"path": "app.js",
"update": "delta"
}
]
如果還會使用到其他的js檔案要載入,在這裡可以加進去"css": [
{
"path": "resources/css/app.css",
"update": "delta"
}
]
3. "url"
build的時候需注意app.json內的url需要設定index.html的路徑
若在本機上設定為
"url": "http://localhost/xxxx/index.html", sencha app build testing|production|package|native
2.檔案目錄my_app_project/build/
my_app_project/build/testing/ 測試用,較方便debug
my_app_project/build/production/ 用來封裝phonegap
my_app_project/build/package/ 放到wb上直接使用
my_app_project/build/native/ 產生native App
常用的會是build成 production,所build出來的版本可以放到web上使用
也可以拿到phonegap上去封裝成APP localStorage.clear()
adb forward tcp:3138 localabstract:chrome_devtools_remote
5.電腦上打開chrome開啟網頁
localhost:3138
會顯示清單,選取要debug的頁面.如果沒有請refresh一下
6.點選要debug的頁面
即可對device做debugnpm -g install weinre
2.執行weinre
設定使用的ip與port 執行
weinre --hostPort 1234 --boundHost 192.168.11.80
使用
1.device端
使用chrome開啟:http://192.168.11.80:1234
頁面上找到target demo,clickproject/build/(放r.js與profile.js)
project/js/(所有專案內的js檔案)
paths : {
_loader:'utils/loader',
_$ : 'libs/jquery/jquery',
...
requireLib:'libs/require/require-min'
}
4.include 設定requirejs的參考({
baseUrl: "../js/",
name: "main",
out: "../js/main.min.js",
paths : {
_loader:'utils/loader',
_$:'libs/jquery/jquery',
_Underscore : 'libs/underscore/underscore',
_Backbone : 'libs/backbone/backbone',
...
requireLib:'libs/require/require-min'
},
include:'requireLib'
})
node r.js -o profile.js
<script data-main="js/main" src="js/libs/require/require.js"></script>
最佳化後使用 <script src="js/main.min.js"></script>
main.js
app.js
router.js
text.js
order.js
views/
models/
collections/
templates/
libs/
baseUrl : 設定所有js找檔案的root節點,
預設是main.js所在路徑,
paths : 將整個project內會用到的檔案或路徑,
在這裡設定別名以方便在module中使用,
使用上以baseUrl下的路徑書寫即可
urlArgs : 可在runtime時替所有js都加入queryString,
避免JS Cache
例require.config({
paths : {
_loader:'utils/loader',
_$ : 'libs/jquery/jquery',
_m:'models',
....
},
urlArgs: "ver=0.0",
});
require(['order!_$','_Backbone','order!_m/InfoModel','order!_c/StoresCollection','order!_app'],function($,Backbone,InfoModel,StoreCollection,App) {
var info=new InfoModel();
var stores=new StoresCollection();
var citys=new CityCollection();
Backbone.emulateHTTP = true;
Backbone.emulateJSON = true;
App.initialize({
info:info,
stores:stores
});
});
define(['_Underscore','_backbone','_$'],function(_,Backbone,$){
return {
}
})
define(function(require){
var $ = require('_$'),
_ = require('_Underscore');
return {
}
})
define([],function(){
return {
....
}
})
2.Router sampleXXRouter.js
define([],function(){
var MyRouter = Backbone.Router.extend({})
return {
myRouter: null,
initialize: function (options) {
this.myRouter = new MyRouter(options);
},
navigate: function (path) {
this.MyRouter.navigate("#" + path, true);
}
}
})
使用XXRouter.initialize()
App.js
define([],function(){
return {
initialize: function (options) {},
......
}
})
使用App.initialize();
App.js
define([],function(){
return {
initialize: function (options) {},
......
}
})
2.Backbone View sampleMyView.js
define(['_backbone'],function(Backbone){
return Backbone.View.extend({
initialize:function(){},
.....
})
})
使用var myView=MyView();
Backbone.emulateHTTP = true;
Backbone.emulateJSON = true;
"create","read","update","delete"
2.REST Server接收到的HTTP METHOD為"POST","GET","PUT","DELETE"
3.非REST Server接收到的$_POST['_method']為"POST","GET","PUT","DELETE"
define(['_Backbone'], function(Backbone) {
return Backbone.Model.extend({
sync:function(method, model, options){
switch(method){
case "create":
options.url =API_Save;
break;
case "update":
options.url = API_Update+"/"+this.id;
break;
case "delete":
options.url = API_Delete+"/"+this.id;
break;
}
return Backbone.sync(method, model, options);
}
})
});
$cmd=$_POST['_method'];
$id=$_GET['id']
switch($cmd){
case "PUT":
$this->_update($id);
break;
case "DELETE":
$this->_delete($id);
break;
case "GET":
$this->_read($id);
break;
case "POST":
$this->_create($id);
break;
}
二.取得model資料$model=$_POST['model'];
if(ini_get("magic_quotes_gpc")=="1"){
$model=stripslashes($model);
};
$obj = json_decode($model);
就可以用$obj.prop..形式來讀取傳進來的json相關屬性了
檔案結構
/ci_application/MyApp1/.htaccess
/ci_application/MyApp1/index.php
/ci_application/MyApp1/app
ubuntu:
cd /etc/apache2/mode-enabled
touch rewrite.load
寫入 LoadModule rewrite_module /usr/lib/apache2/modules/mod_rewrite.so
window
開啟 conf/httpd.conf
LoadModule rewrite_module modules/mod_rewrite.so
2.http conf設定在相關的<directory>內</directory><br />
AllowOverride All(none都改成All)
RewriteBase /ci_application/myapp1/
2.index.php設定例:目前的設定都是把application目錄放在Project下
web_root/ci_application/MyApp1/app
$application_folder='app'
system目錄統一放在CodeIgniter目錄下
web_root/codeIgniter/system
$system_path='../../codeIgniter/system'
3.app內的config.php設定$config['base_url'] = 'http://192.168.2.104/ci_app/myApp1/';
//設定index_page為空白,就可以讓網址上看不到index.php(只看到路徑/ci_application/myApp1/)$config['index_page'] = '';
4.app內的database.php設定window.SM2_DEFER = true;
window.soundManager = new SoundManager();
soundManager.url = "swf/";
soundManager.beginDelayedInit();
這樣就可以保證可以安全運作了 <div class="wrapper">
<div class='header'></div>
<div id='myContent' class="content">
<div class='scroller'><div class='itemContainer'></div></div>
</div>
<div class="footer"></div>
</div>
要scroll的內容下需有一個唯一的子節點(div或ul都可),iScroll會對這個div做scroll.wrapper{
position:absolute;z-index:1;//以絕對位置設定當作最下層layer
top:0;left:0;//設定貼在browser的最左上方
margin:0;padding:0;
width:300px;//可以用%設定
height:300px;
}
4.header .header{
position:absolute;z-index:3;//設定在最上層
top:0;left:0;//設定貼在wrapper的靠左上方
margin:0;padding:0;
width:100%;//設定與wrapper相同寬度
height:50px;//設定header的絕對高度
}
5.footer.footer{
position:absolute;z-index:3;//設定在最上層
bottom:0px;left:0;//設定貼在wrapper的靠左下方
margin:0;padding:0;
width:100%;//設定與wrapper相同寬度
height:50px;//設定header的絕對高度
}
6.content.content{
position:absolute;z-index:2;//設定在中間層
top:50px;//設定在header的下方,也就是設定header的高度
left:0;
margin:0;padding:0;
width:100%;
height:200px;//設定wrapper扣掉header與footer後的高度,這部份由js動態改變值
overflow:auto;//設定內部的所有內容在超過的時候以scroll顯示
>.scroller{
width:100%;//注意千萬不要設定height,內容超過時才可以scroll
>.itemContainer{
width:100%;//注意千萬不要設定height,內容超過時才可以scroll
}
}
}
window.scroll=new iScroll('myContent',{
hScrollBar:false,
vScrollBar:true,
hideScrollBar:false
})
2.refreshsetTimeout(function(){
window.scroll.refresh();
},0)