<html lang="en" xmlns="http://www.w3.org/1999/xhtml"> <head> <meta charset="utf-8" /> <title>angular directive 連動選單</title> <script src="../Scripts/angular.min.js"></script> <script> var app = angular.module('myApp', []); // directive app.directive('categorySelection', function ($http) { var _template = '<div>' + // 第一分類 '<select class="category-first form-control" ng-model="selectedCategory.first">' + '<option value="0">--第一分類--</option>' + '<option ng-repeat="f in categorySelection.firsts" value="{{f.Id}}">{{f.Text}}</option>' + '</select>' + // 第二分類 '<select class="category-second form-control" ng-model="selectedCategory.second">' + '<option value="0">--第二分類--</option>' + '<option ng-repeat="s in categorySelection.seconds" value="{{s.Id}}">{{s.Text}}</option>' + '</select>' + // 第三分類 '<select class="category-third form-control" ng-model="selectedCategory.third">' + '<option value="0">--第三分類--</option>' + '<option ng-repeat="t in categorySelection.thirds" value="{{t.Id}}">{{t.Text}}</option>' + '</select>' + '</div>'; return { restrict: 'E', scope: { first: '=', // 第一分類, 用"等於"符號做雙向綁定 second: '=', // 第二分類 third: '=' // 第三分類 }, controller: function ($scope) { // 已經被選取的分類 $scope.selectedCategory = { first: 0, second: 0, third: 0 }; // 分類選項 $scope.categorySelection = {}; $scope.categorySelection.firsts = []; $scope.categorySelection.seconds = []; $scope.categorySelection.thirds = []; }, replace: true, template: _template, link: function (scope) { // 取第一類選項資料 refeshCategorySelection('first'); // 第一分類選項異動, 更新第二分類選項 scope.$watch("selectedCategory.first", function () { scope.first = parseInt(scope.selectedCategory.first, 10); if (scope.first !== 0) { refeshCategorySelection('second', scope.first); } else { scope.categorySelection.seconds = []; scope.categorySelection.thirds = []; } }); // 第二分類選項異動, 更新第三分類選項 scope.$watch("selectedCategory.second", function () { scope.second = parseInt(scope.selectedCategory.second, 10); if (scope.second !== 0) { refeshCategorySelection('third', scope.second); } else { scope.categorySelection.thirds = []; } }); // 第三分類選項異動 scope.$watch("selectedCategory.third", function () { scope.third = parseInt(scope.selectedCategory.third, 10); }); // 更新選單 function refeshCategorySelection(type, id) { $http.get('/Home/GetData?id=' + id).success(function (data) { switch (type) { case 'first': scope.categorySelection.firsts = data; scope.categorySelection.seconds = []; // 清空第二分類選單 (template上剩下預設的"--第二分類--"選項) scope.categorySelection.thirds = []; scope.selectedCategory.first = 0; // 設定館分類被選取值 (讓被選取值回到"--第一分類--"選項上) scope.selectedCategory.second = 0; scope.selectedCategory.third = 0; break; case 'second': scope.categorySelection.seconds = data; scope.categorySelection.thirds = []; scope.selectedCategory.second = 0; scope.selectedCategory.third = 0; break; case 'third': scope.categorySelection.thirds = data; scope.selectedCategory.third = 0; break; default: break; } }); } } } }); // controller app.controller('homeCtrl', function ($scope) { $scope.query = {}; $scope.query.first = 0; $scope.query.second = 0; $scope.query.third = 0; $scope.onSend = function () { console.log($scope.query); }; }); </script> </head> <body ng-app="myApp" ng-controller="homeCtrl"> <category-selection first="query.first" second="query.second" third="query.third"></category-selection><button ng-click="onSend()">Send</button> </body> </html>
2015年8月14日 星期五
angular directive 連動選單
2015年5月24日 星期日
NSDate
Apple官方文件說明NSDate:
https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSDate_Class/index.html
https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSDate_Class/index.html
// 當地日期時間,沒有秒。ex : "May 25, 2015, 11:30 AM"
let date = NSDate()
// 格式化
var formatter = NSDateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss ZZZ"
let defaultTimeZonStr = formatter.stringFromDate(date) // 同樣的日期時間,但是有秒。ex : "2015-05-25 11:34:21 +0800"
formatter.timeZone = NSTimeZone(abbreviation: "UTC")
let utcTimeZoneStr = formatter.stringFromDate(date) // 同樣的日期時間,但是在UTC。ex : "2015-05-25 03:34:21 +0000"
// 設定日期
var endDate = NSDate().dateByAddingTimeInterval(30 * 60) // 30 minutes from current time
// 日期比較
var dateComparisionResult:NSComparisonResult = NSDate().compare(endDate)
if dateComparisionResult == NSComparisonResult.OrderedAscending
{
println("當前日期時間比 end date 小.") // 這個範例中,這個結果會被打印出來
}
else if dateComparisionResult == NSComparisonResult.OrderedDescending
{
println("當前日期時間比 end date 大.")
}
else if dateComparisionResult == NSComparisonResult.OrderedSame
{
println("當前日期時間與 end date 相同.")
}
// iOS 8.0+ 的 NSCalendar 方法
var cal = NSCalendar.currentCalendar()
cal.startOfDayForDate(endDate) // 忽略時間元素,ex : "May 25, 2015, 12:00 AM"
cal.isDateInToday(endDate) // 指定日期是否為今天。其他的還有
cal.isDateInTomorrow(endDate)
cal.isDate(NSDate(), inSameDayAsDate: endDate) // 比對兩個日期是否相同
// 字串轉為日期
var dataString = "April 1, 2015" as String
var dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "MM-dd-yyyy"
dateFormatter.timeZone = NSTimeZone.localTimeZone()
let dateValue = dateFormatter.dateFromString(dataString) as NSDate!
println(dateValue) // ex : "Apr 1, 2015, 12:00 AM"
格式化:
類似“/Date(1427909016000-0800)”格式的timestamp,要轉成NSDate:
func timestampToNSDate(jsonDate: String) -> NSDate? {
let prefix = "/Date("
let suffix = ")/"
let scanner = NSScanner(string: jsonDate)
// Check prefix:
if scanner.scanString(prefix, intoString: nil) {
// Read milliseconds part:
var milliseconds : Int64 = 0
if scanner.scanLongLong(&milliseconds) {
// Milliseconds to seconds:
var timeStamp = NSTimeInterval(milliseconds)/1000.0
// Read optional timezone part:
var timeZoneOffset : Int = 0
if scanner.scanInteger(&timeZoneOffset) {
let hours = timeZoneOffset / 100
let minutes = timeZoneOffset % 100
// Adjust timestamp according to timezone:
timeStamp += NSTimeInterval(3600 * hours + 60 * minutes)
}
// Check suffix:
if scanner.scanString(suffix, intoString: nil) {
// Success! Create NSDate and return.
return NSDate(timeIntervalSince1970: timeStamp)
}
}
}
return nil
}
timestampToNSDate("/Date(1427909016000-0800)/")
2015年1月29日 星期四
閉包 Closures - 高階函式 Higher-order functions
func connect(str1 : String, str2 : String) -> String {
return str1 + " " + str2
}
connect("hello","world") // "hello world"
func say(name : String, function : (String, String) -> String) -> String{
let greet = "你好"
var str = function(name, greet)
return str
}
// 1. 函數被當成變數傳入另一個函數
var result = say("Ian",connect)
println(result) // "Ian 你好"
// 2. 閉包運算式(Closure Expressions)
// 把connect函數的名稱用函數型態取代,in關鍵字之後為程式碼內容。
result = say("Peter", { (str1:String, str2:String) -> String in
return str1 + " " + str2
})
println(result) // "Peter 你好"
// 3. 根據上下文推斷型態(Inferring Type From Context)
result = say("Alex", { str1, str2 in
return str1 + " " + str2
})
println(result)// "Alex 你好"
// 4. 閉包單行表示式隱含返回(Implicit Return From Single-Expression Clossures)
// 拿掉return關鍵字
result = say("Jay", { str1, str2 in str1 + " " + str2 })
println(result) // "Jay 你好"
// 5. 參數名稱縮寫(Shorthand Argument Names)
// 直接通過$0,$1,$2...來順序引用閉包的參數
result = say("Alice", { $0 + " " + $1 })
println(result) // "Alice 你好"
// 6. 運算符函數(Operator Functions)
// 簡單地傳遞一個加號,Swift可以自動推斷出我們想使用加號的字串函數操作。
result = say("Bob", + )
println(result) // "Bob 你好"
// 尾隨閉包(Trailing Closures)
// 把最後一個參數(閉包函數)搬出參數列括弧,整個大括弧搬出小括弧之外。當閉包內容冗長的時候,適合這樣表達。
result = say("Tim"){
(str1 : String, str2 : String) -> String in return str1 + str2
}
println(result) // "Tim 你好"
======================================
使用 Javascript 的範例,改寫成 Swift 版
http://ianworkshop.blogspot.tw/2014/03/blog-post.html
高階函示 :
1. 把其他函式當作引數 (callback function / 回呼函式, 即呼叫時傳入她, 然後她再呼叫回來)
2. 會回傳函式
- 使用標準程式庫原本的方法
// 將陣列中的數值由小到大重新排列
var nums = [1,3,5,7,9,8,6,4,2]
// 2. 閉包運算式
nums.sort({ (n1:Int, n2:Int) -> Bool in
n1 < n2
})
println(nums)
// 3. 推斷型態
nums.sort({ n1, n2 in
return n1 < n2
})
// 4. 隱含返回 (拿掉return關鍵字)
nums.sort({ n1, n2 in n1 < n2 })
// 5. 參數名稱縮寫
nums.sort({ $0 < $1 })
// 6. 運算符函數
nums.sort( < )
// 7. 尾隨閉包
nums.sort{ (n1:Int, n2:Int) -> Bool in
n1 < n2
}
// 尾隨閉包 + 參數名稱縮寫
nums.sort{ $0 < $1 }
======
// 將陣列中的字串都轉為大寫
var names = ["Ian","Peter","Kevin"]
// 尾隨閉包 + 參數名稱縮寫
// 尾隨閉包 + 參數名稱縮寫
names = names.map { $0.uppercaseString }
println(names) // "[IAN, PETER, KEVIN]"
- 自訂高階函式
// 依照條件建立字串
func builderString(n:Int, callback:(counting:Int) -> String ) -> String {
var result = "";
for i in 0...n {
result = result + callback(counting: i)
}
return result
}
// 建立 1~9
var digits_1 = builderString(8, { (counting) -> String in
return "\(counting+1)"
})
var digits_2 = builderString(8) { "\($0+1)"}
2015年1月21日 星期三
Status Bar
Xcode 6.1.1
這一個是 Status Bar

隱藏:
在專案下的 General > Deployment Info 有一個選項 Hide status bar,打勾後啟動專案發現並沒有消失,所以這個功能沒有作用。
到 Navigator 下找到在 Supporting Files 資料夾裡的 Info.plist,click 右鍵 > Open As > Source Code,在 <dict> 裡面加入:
這一個是 Status Bar
隱藏:
在專案下的 General > Deployment Info 有一個選項 Hide status bar,打勾後啟動專案發現並沒有消失,所以這個功能沒有作用。
到 Navigator 下找到在 Supporting Files 資料夾裡的 Info.plist,click 右鍵 > Open As > Source Code,在 <dict> 裡面加入:
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
再次執行專案就看不到 Status Bar 了,對 Info.plist 點擊右鍵 > Open As > Property List,可以看到多了一個 key-value pair:
也可以直接在 Property List 中加入
改變顏色:
在狀態列是開啟的情況時,如果在白色背景下將某個 View 的 Status Bar 設為亮色系,也有隱藏效果
override func preferredStatusBarStyle() -> UIStatusBarStyle {
return .LightContent
}
如果將背景改為黑色,則顯示如圖所示:
2015年1月19日 星期一
AJAX 與 [Authorize]
ASP.NET MVC 在 Controller 或 Action 上加上 [Authorize] 就可以驗證是否已經登入,如果沒有登入就會被帶往登入頁面
當使用ajax方式則會得到狀態為200的頁面(指定的頁面),因此需要改寫可以回傳一個Json :
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class MyAuthorizeAttribute : AuthorizeAttribute
{
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
if (filterContext.HttpContext.Request.IsAjaxRequest())
{
filterContext.Result = new JsonResult
{
Data = new
{
// put whatever data you want which will be sent
// to the client
message = "sorry, but you were logged out"
},
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
else
{
base.HandleUnauthorizedRequest(filterContext);
}
}
}
$.get('@Url.Action("SomeAction")', function (result) {
if (result.message) {
alert(result.message);
} else {
// do whatever you were doing before with the results
}
});
如果是用 AngularJs,IsAjaxRequest 會一直判斷是 false,因為 AngularJs 的 ajax 呼叫沒有包含 X-Requested-With 表頭,而 ASP.NET MVC 是用這個表來判斷是否為一個 ajax 呼叫,所以必須改為:}]);var productsApp = angular.module('productsApp', []);productsApp.config(['$httpProvider', function ($httpProvider) {$httpProvider.defaults.headers.common["X-Requested-With"] = 'XMLHttpRequest';
訂閱:
文章 (Atom)