[英]AngularJS 1.4: How to create two-way binding using bindToController and controllerAs syntax
[英]AngularJS - DRY two-way data-binding using controllerAs syntax and service properties
我偶然發現了一個應該是常見且明顯的問題,但我似乎無法繞過它。
我正在研究一個小型原型應用程序。 我的后端開發人員在JSON對象中為我提供了配置文件數據。 讓我們說,它看起來像這樣:
profile = {Name: 'John', Email: 'john@mail.com', DOB: '1980-11-03'}
我需要在多個位置使用這些值,我也不想在控制器中放置后端http調用,所以我創建了一個服務來處理這個:
angular.module('app', [])
.service('ProfileService', ['$http', function ($http) {
var service = this;
service.Name = null;
service.Email = null;
service.DOB = null;
service.getProfile = function () {
return $http.get('/profile').then(function (response) {
service.Name = response.data.Name;
service.Email = response.data.Email;
service.DOB = response.data.DOB;
return true;
});
};
return service;
}])
.controller('ProfileCtr', ['ProfileService', function (service) {
var vm = this;
service.getProfile().then(function () {
vm.Name = service.Name;
vm.Email = service.Email;
vm.DOB = service.DOB;
});
}]);
此解決方案存在許多問題:
一種解決方案是添加一個間接層並在服務中創建一個對象:
angular.module('app', [])
.service('ProfileService', ['$http', function ($http) {
var service = this;
service.profile = {};
service.getProfile = function () {
return $http.get('/profile').then(function (response) {
for (key in response.data) {
service.profile[key] = response.data[key];
};
return true;
});
};
return service;
}])
.controller('ProfileCtr', ['ProfileService', function (service) {
var vm = this;
service.getProfile().then(function () {
vm.profile = service.profile;
});
}]);
這通常有效,但現在我的控制器語法變得笨拙:
<div ng-controller="ProfileCtr as ctr">
<h1> {{ ctr.profile.Name }}</h1>
<p> Email: {{ ctr.profile.Email }} <br /> DOB: {{ ctr.profile.DOB }}</p>
</div>
我想知道是否有一種方法可以同時給我:干凈的HTML {{ ctr.Name }}
語法和 DRY編程風格。
謝謝你的任何提示!
我有一種感覺,你想要更多,但這對我來說至少是干的:
angular.module('app', [])
.service('ProfileService', ['$http', function ($http) {
var service = this;
service.getProfile = function () {
return $http.get('/profile').then(function (response) {
return response.data;
});
};
return service;
}])
.controller('ProfileCtr', ['ProfileService', function (ProfileService) {
var vm = this;
ProfileService.getProfile().then(function (profile) {
vm.profile= profile;
});
}]);
該服務獲取數據。 您也可以在此處添加緩存功能。 控制器使用該服務來獲取數據。 沒有重復的代碼。
我喜歡使用$scope
變量,這將刪除單層間接問題。 但是,控制器確實具有它的優點,特別是如果您使用嵌套控制器並希望清楚使用哪個控制器。 $scope
標識符將在版本2中刪除。
使用html的這一部分而不是控制器的指令應該使代碼更容易閱讀和重用。 建議將其升級到版本2。
然后:
app.directive('isolateScopeWithControllerAs', function () {
var controller = ['ProfileService', function (ProfileService) {
var vm = this;
ProfileService.getProfile().then(function (profile) {
vm.profile= profile;
});
}];
return {
restrict: 'EA', //Default for 1.3+
controller: controller,
controllerAs: 'vm',
bindToController: true, //required in 1.3+ with controllerAs
templateUrl: // path to template
};
});
然后你的HTML仍然給你:
<h1> {{ vm.profile.Name }}</h1>
<p> Email: {{ vm.profile.Email }} <br /> DOB: {{ vm.profile.DOB }}</p>
如果您將指令用於多個對象,則ProfileCtr as vm
會更有用。 例如,如果您有一個用戶指令,那么您可以:
controllerAs: 'user',
with user.profile.name
和ng-repeat='friend in user.friends'
等。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.