摘要:angularjs初體驗<利用YQL擷取中央氣象局網頁內容>
其實在去年底的時候,就看到很多前輩已經開始在分享AngularJS.
不過卻沒時間好好去消化去瞭解AngularJS的精妙.
剛好趁這一兩天有些零碎的時間
透過之前做過的範例<透過Jquery利用YQL擷取中央氣象局網頁內容>,
看著前輩的發表的文章手把手,步步實作.
轉換為angularjs的架構
接下來就獻醜嚕
其實在實作的過程中,我想遇到最大的困難點,
應該是習慣了jquery對元素的操作已經習慣,
突然要抽離還是會有點不習慣.
當然AngularJS也有提供對DOM元素操作的方法jqLite.
基本上是從Jquery抽離而來的常用功能
先看一下HTML的部分
<!DOCTYPE html>
<html ng-app="myFirstAppDemo">
<head>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.28/angular.min.js"></script>
<script src="http://code.angularjs.org/1.2.13/angular-animate.js"></script>
<script src="js/myFirstAppDemo.js"></script>
<link href="css/Style.css" rel="stylesheet" />
<meta charset="utf-8">
<title>angular_APP_DEMO</title>
</head>
<body ng-controller="MySelectCtrl" ng-init="action('TaipeiCityList')">
<p class="divfix">縣市:
<select ng-model="Selectcityarr" ng-options="m.city.name for m in cityarr" ng-change="action(Selectcityarr.city.id)">
<option value="">-- 請選擇 --</option>
</select>
</p>
<table >
<!-- 放置內容區域-->
<td width="100px;">
<p >日期</p>
<p >{{timeNow | date:"yyyy/MM/dd"}}</p>
</td>
<td width="100px;">
<p>縣市</p>
<p ng-show="data.active" class="fadein fadeout">{{rtval.name}}</p>
</td>
<td width="100px;">
<p>溫度</p>
<p ng-show="data.active" class="fadein fadeout">{{rtval.temp}}</p>
</td>
<td width="100px;">
<p>降雨機率</p>
<p ng-show="data.active" class="fadein fadeout">{{rtval.percent}}</p>
</td>
<td width="100px;">
<div class="spic divfix">
<p class="pfix">示意圖</p>
<img ng-src="http://www.cwb.gov.tw/{{rtval.imgurl}}" width="45" height="45" border="0" ng-show="data.active" class="fadein fadeout">
</div>
</td>
</table>
</body>
</html>
在這邊看到在HTML上比較特殊的地方
,會有像ng-app,ng-model等TAG.
在這邊稱為宣告式語法<詳細說明請參考>
透過這個方式,讓angularjs可以存取控制這份HTML.
也像是一種定義範圍!
這邊我先解釋一下ng-model這一塊,
其實當時在捉摸這一部分的時候,還是有點困惑.
但經過一些前輩的文章上的講解
原來是透過ng-model
讓HTML跟AngularJs可以相互溝通
簡單來說就是可以在angularJs中取得使用者在HTML上操作所變化的值
例如
在範例中下拉式清單裡
我在ng-model定義一個變數 "Selectcityarr"
在 ng-change這個TAG中我放入一個function
裡面要求放入的參數則是使用者切換下拉清單中的選項後帶入的值
所以帶入Selectcityarr.city.id
至於下拉是清單的值產出方式則可以參考<搞懂 AngularJS 預設模組 select 標籤的 ngOptions 參數用法>
接下來
看看JS的部分嚕
解說的部分大多都在Code裡嚕
/*
在此定義module名稱,與引用的model
myFirstAppDemo-自定義名稱,對應到HTML中的ng-app
ngAnimate-引用<畫面特效>
*/
var app = angular.module('myFirstAppDemo', ['ngAnimate']);
/*
在此定義controller名稱,與引用的所會用到服務
MySelectCtrl-自定義名稱,對應到HTML中的ng-controller
$scope-控制在HTML與angular之間橋樑如在JS中$scope.rtval.percent ,
在HTML上要輸出則{{ rtval.imgurl}} ,
或是在HTML TAG上加上 ng-bind="rtval.percent"
$http-Ajax服務
*/
app.controller('MySelectCtrl', ['$scope', '$http',
function Action($scope, $http) {
//回傳值
$scope.rtval = new Object();
//顯示今日時間
$scope.timeNow = Date.now();
//縣市選單
$scope.cityarr = [
{
"city": {
"id": "KeelungList",
"name": "基隆市"
}
},
{
"city": {
"id": "TaipeiCityList",
"name": "臺北市"
}
},
{
"city": {
"id": "TaipeiList",
"name": "新北市"
}
},
{
"city": {
"id": "TaoyuanList",
"name": "桃園縣"
}
},
{
"city": {
"id": "HsinchuCityList",
"name": "新竹市"
}
},
{
"city": {
"id": "HsinchuList",
"name": "新竹縣"
}
},
{
"city": {
"id": "MiaoliList",
"name": "苗栗縣"
}
},
{
"city": {
"id": "TaichungList",
"name": "臺中市"
}
},
{
"city": {
"id": "ChanghuaList",
"name": "彰化縣"
}
},
{
"city": {
"id": "NantouList",
"name": "南投縣"
}
},
{
"city": {
"id": "YunlinList",
"name": "雲林縣"
}
},
{
"city": {
"id": "ChiayiCityList",
"name": "嘉義市"
}
},
{
"city": {
"id": "ChiayiList",
"name": "嘉義縣"
}
},
{
"city": {
"id": "YilanList",
"name": "宜蘭縣"
}
},
{
"city": {
"id": "HualienList",
"name": "花蓮縣"
}
},
{
"city": {
"id": "TaitungList",
"name": "臺東縣"
}
},
{
"city": {
"id": "TainanList",
"name": "臺南市"
}
},
{
"city": {
"id": "KaohsiungCityList",
"name": "高雄市"
}
},
{
"city": {
"id": "PingtungList",
"name": "屏東縣"
}
},
{
"city": {
"id": "MatsuList",
"name": "連江縣"
}
},
{
"city": {
"id": "KinmenList",
"name": "金門縣"
}
},
{
"city": {
"id": "PenghuList",
"name": "澎湖縣"
}
}];
//下拉式清單更動事件
$scope.action = function ( cityId) {
getWeather(cityId);
};
/*網頁Loaded如:jquery ready事件或者在TAG中添加ng-init
angular.element(document).ready(function () {
getWeather('TaipeiCityList');
});
*/
//透過YQL取得中央氣象局天氣資訊(當日)
function getWeather(citycode) {
$scope.data = { active: false };
var BasicQueryUrl = 'http://query.yahooapis.com/v1/public/yql?';
var query = 'q=' +
encodeURIComponent('select * from html where ' +
' url = "http://www.cwb.gov.tw/V7/forecast/f_index.htm" and ' +
'xpath=' + "'" + '//tr[@id="' + citycode + '"]' + "'") + '&format=json';
$http({
method: 'GET',
url: BasicQueryUrl + query
})
.success(function (data, status, headers, config) {
$scope.data = { active: true };
var lastImglength = data.query.results.tr.td.length - 1;
angular.forEach(data.query.results.tr.td, function (value, key) {
if (value.a.content !== undefined) {
var name = '';
switch (key) {
case 0:
//"縣市";
$scope.rtval.name = value.a.content;
break;
case 1:
//"溫度";
$scope.rtval.temp = value.a.content;
break;
case 2:
//"降雨機率";
$scope.rtval.percent = value.a.content;
break;
}
}
});
var iurl = data.query.results.tr.td[lastImglength].div.img.src;
$scope.rtval.imgurl = iurl;
})
.error(function (data, status, headers, config) {
});
};
}
]);
接下來就來解釋一下CSS的部分,
這當時也是讓我有點小卡關的部分,
但看了一下官網的解說跟範例,
在做一些特殊效果,除了在HTML中加入
ng-show,ng-hide..etc 這些宣告式語法
但實際上真正做動的地方是在CSS裡
請參考<Adding CSS Animations to AngularJS Applications>
當然也可以透過JS直接做特效的部分
請參考<博弈AngularJS講義(13)>
如範例中
JS裡有引用ngAnimate
提供了特效的事件與方法
須先加入此library
<script src="http://code.angularjs.org/1.2.13/angular-animate.js"></script>
CSS
/*淡入淡出效果*/ .fadein, .fadeout { -webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s; -moz-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s; -o-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s; transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s; } /* 透過$scope.rtval.active此變數 為false時 透過.ng-hide-add-active此事件做隱藏 */ .fadeout.ng-hide-add-active { opacity: 0; display: block !important; } /* 透過$scope.rtval.active此變數 為true時 透過.ng-hide-remove-active此事件做呈現 */ .fadein.ng-hide-remove-active { opacity: 1; display: block !important; }
其實寫完之後,會發現各個之間互動變得很單純
HTML,javascript,CSS各司其職
相對的維護性也提高
當然直接對DOM元素操作變少了
對習慣Jquery操作的使用者,
會有一個轉換時間.
在此如果寫得不好也請各位前輩多多指導!
參考連結
Day2- 入門AngularJS筆記-AngularJS指令(1): ng-model
Adding CSS Animations to AngularJS Applications