AngularJS (11) $http.get + templateUrl + scope 讀檔後匯入樣版
本篇完整程式碼請看Plunkr
我們在前一篇也說過,控制器可以定義值,再透過它範疇內的宣告標籤傳值到樣版。範疇的大致概念如下:
<div ng-controller="某控制器"> <宣告標籤></宣告標籤> </div>
而樣版就像是句型一樣,讓我們可以餵值進去。
但是,如果餵進去的數值很多時,有沒有可能用讀檔的方式把大量的值傳給樣版呢?答案是可以。
大致解法是,先用$http.get()讀變數檔,再透過宣告標籤的templateUrl、scope將$http.get()的值餵給樣版。這麼說有點籠統(掩面),我們來看實例吧。
實例
今天你有了六個朋友的資訊,人名、地址,希望把他們照某個樣版顯示。
Lily Hualien Ihc TsiongHua Suisui2 Hualien Suisui Hualien Piggu Hualien Chhueh TsiongHua
I'm ________, and I come from ________. 這是你想要的樣版。
朋友資訊那麼多,而且以後還會一直增加新好友,你當然就不希望把朋友資訊寫死在script,以免不容易維護程式。所以,最好的解法就是把你朋友的資料寫在一個文字檔,並用script去讀取它。
朋友資訊.txt
Lily Hualien Ihc TsiongHua Suisui2 Hualien Suisui Hualien Piggu Hualien Chhueh TsiongHua
template.html
I'm {{friendName}}, and I come from {{friendAddr}}.<br/>
它存了句型I'm ________, and I come from ________.。
人名和地址的填空處用樣版變數friendName,friendAddr表示。
JS 第一步:在控制器用$http.get()讀檔
要能夠顯示朋友的資料,當然首要做的就是讀出朋友資訊.txt的值,存到某個陣列變數內。作法如下
app = angular.module("app1",[]); app.controller('NameController', ['$scope', '$http', function($scope, $http) { $scope.list = []; $http.get('namelist.txt').success(function(data){ angular.forEach(data.split('\n'), function(line, ind){ var words = line.split(' '); console.log(words); $scope.list.push({'name': words[0], 'addr': words[1]}); }); });//end $http }]);
一開始,為了用$http.get()讀檔,['$http',...]讓控制器可以使用angularJS的$http服務。
app.controller('NameController', ['$scope', '$http', function($scope, $http) {
為了待會存入一組組朋友的名字和地址,我們初始化了一個空的list陣列變數。
$scope.list = [];並且希望,待會做完讀檔後,list會像這樣
$scope.list = [{名字1, 地址1},{名字2, 地址2},...,{名字N, 地址N}];
確定好要得到的list格式後,我們用$http.get().success()寫明讀檔後要接著執行什麼事情。
$http.get('朋友資訊.txt').success(function(data){而.success()裡的data=
Lily Hualien\n Ihc TsiongHua\n Suisui2 Hualien\n Suisui Hualien\n Piggu Hualien\n Chhueh TsiongHua\n但是和我們想要在控制器得到的不太一樣
$scope.list = [{名字1, 地址1},{名字2, 地址2},...,{名字N, 地址N}];
所以我們要在.success()裡頭寫個parser,從data的換行字元、空白字元分割出一組組人名和地址。
angular.forEach(data.split('\n'), function(line, ind){ var words = line.split(' '); $scope.list.push({'name': words[0], 'addr': words[1]}); });
完成上述的所有步驟後,我們得到
$scope.list = [ {name:"Lily", addr:"Hualien"}, {name:"Ihc, addr:"TsiongHua"}, {name:"Suisui2", addr:"Hualien"}, {name:"Suisui", addr:"Hualien"}, {name:"Piggu", addr:"Hualien"}, {name:"Chhueh", addr:"TsiongHua"} ];
JS 第二步:新增宣告標籤
因為我們要連結控制器的$scope.list到樣版變數,所以要寫宣告標籤。
app.directive("myInfo", function(){ return { restrict:'E', templateUrl:'template.html', scope: { friendName: '=infoName', friendAddr: '=infoAddr' } }; });
我們定義了一個宣告標籤,叫做myInfo
app.directive("myInfo",
指定myInfo是自定元素,所以待會在網頁使用myInfo時可以寫成標籤<my-info>
restrict:'E',
myInfo的任務是,連結樣版,所以需要用templateUrl參數。
templateUrl:'template.html',
myInfo能夠連結樣版後,為了在網頁時,控制器可以透過<my-info>傳值給樣版,所以我們用scope參數新增兩個屬性。
scope: { friendName: '=infoName', friendAddr: '=infoAddr' }friendName 和 friendAddr 是樣版的填空處的變數。還記得我們的樣版嗎?
I'm {{friendName}}, and I come from {{friendAddr}}.<br/>
infoName 和 infoAddr 則是我們幫宣告標籤<my-info>新增的屬性。有什麼用處?留著這個疑問,先往下看網頁的寫法。
index.html
<body ng-app="app1"> <div ng-controller="NameController"> <my-info ng-repeat="man in list" info-name="man.name" info-addr="man.addr"></my-info> </div> </body>
※infoName、infoAddr是js的寫法,在html要寫成info-name、info-addr
因為我們要從控制器的$scope.list,取出每一組人名地址丟給樣版,所以這麼寫
<my-info ng-repeat="man in list" info-name="man.name" info-addr="man.addr"> </my-info>
其中有我們為<my-info>新增的屬性,info-name 和 info-addr。
它們在網頁中,被餵入一組組的人名和地址
info-name="man.name" info-addr="man.addr"
info-name 和 info-addr 得到值之後呢?
就要看我們在JS第二步新增的屬性:
scope: { friendName: '=infoName', friendAddr: '=infoAddr' }
因此,info-name 和 info-addr 得到值之後,傳給樣版的friendName 和 firendAddr。
也就是,
在js定義了餵值給樣版的屬性,於是,在html把控制器的值餵給屬性,再透過屬性把值傳給樣版。
完成
I'm Ihc, and I come from TsiongHua.
I'm Suisui2, and I come from Hualien.
I'm Suisui, and I come from Hualien.
I'm Piggu, and I come from Hualien.
I'm Chhueh, and I come from TsiongHua.
完整JS
var app = angular.module("app1",[]); /*JS 第一步*/ app.controller('NameController', ['$scope', '$http', function($scope, $http) { //$scope.names = []; $scope.list = []; $http.get('namelist.txt').success(function(data){ angular.forEach(data.split('\n'), function(line, ind){ //$scope.names.push({name:line}); var words = line.split(' '); $scope.list.push({'name': words[0], 'addr': words[1]}); }); console.log($scope.list); });//end $http }]); /*JS 第二步*/ app.directive("myInfo", function(){ return { restrict:'E', scope: { friendName: '=infoName', friendAddr: '=infoAddr' }, templateUrl:'template.html' }; });
留言
張貼留言