Mic*_*ber 5 javascript dry angularjs
我偶然发现了一个应该是常见且明显的问题,但我似乎无法绕过它.
我正在研究一个小型原型应用程序.我的后端开发人员在JSON对象中为我提供了配置文件数据.让我们说,它看起来像这样:
profile = {Name: 'John', Email: 'john@mail.com', DOB: '1980-11-03'}
Run Code Online (Sandbox Code Playgroud)
我需要在多个位置使用这些值,我也不想在控制器中放置后端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;
});
}]);
Run Code Online (Sandbox Code Playgroud)
此解决方案存在许多问题:
一种解决方案是添加一个间接层并在服务中创建一个对象:
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;
});
}]);
Run Code Online (Sandbox Code Playgroud)
这通常有效,但现在我的控制器语法变得笨拙:
<div ng-controller="ProfileCtr as ctr">
<h1> {{ ctr.profile.Name }}</h1>
<p> Email: {{ ctr.profile.Email }} <br /> DOB: {{ ctr.profile.DOB }}</p>
</div>
Run Code Online (Sandbox Code Playgroud)
我想知道是否有一种方法可以兼顾我:干净的HTML {{ ctr.Name }}语法和
干燥的编程风格.
谢谢你的任何提示!
我有一种感觉,你想要的不仅仅是这个,但这对我来说至少是干的:
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;
});
}]);
Run Code Online (Sandbox Code Playgroud)
该服务获取数据。您也可以在此处添加缓存功能。控制器使用该服务来获取数据。没有重复的代码。
我喜欢使用$scope变量,这将消除一层间接问题。然而,controllerAs 确实有它的优点,特别是如果您使用嵌套控制器并且想要清楚您正在使用哪个控制器。并且该$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
};
});
Run Code Online (Sandbox Code Playgroud)
然后你的 HTML 仍然给你:
<h1> {{ vm.profile.Name }}</h1>
<p> Email: {{ vm.profile.Email }} <br /> DOB: {{ vm.profile.DOB }}</p>
Run Code Online (Sandbox Code Playgroud)
ProfileCtr as vm如果您将该指令用于多个对象,则该指令会更有用。例如,如果您有一个用户指令,那么您可以:
controllerAs: 'user',
Run Code Online (Sandbox Code Playgroud)
与等user.profile.nameng-repeat='friend in user.friends'
| 归档时间: |
|
| 查看次数: |
543 次 |
| 最近记录: |