0

我的模块中有以下代码:

.controller('ModalInstanceCtrl', function($rootScope, $scope, emailService) {
    $scope.emailService = emailService; // Good or not; if not, why?
    $scope.showed = false;
    $rootScope.$watch('showed', function () { $scope.showed = $rootScope.showed; }); // In case you wonder why I did this - I'm using this trick to prevent watch from firing twice, because that would happen if I remove the watch below and put its code here.
    $scope.$watch('showed', function () {
        if (!$rootScope.showed) return;
        $scope.selected = 0;
        $scope.primary = true;
        $scope.verified = true;
        if (emailService.emails.length == 0) emailService.load();
    });
    $scope.EmailSelected = function () {
        emailService.setCurrent($scope.selected);
        $scope.primary = emailService.emails[$scope.selected].primary;
        $scope.verified = emailService.emails[$scope.selected].verified;
    };
});

.factory('emailService', function($resource, $http) {
    var emails = []; // [{email: 'sample@email.dom', verified: true, primary: false}, ...]
    var selected = 0;

    function sendreq(action, email){
        $http({
            method: 'POST',
            url: '/email/',
            data: "action_" + action + "=&email=" + email,
            headers: {'Content-Type': 'application/x-www-form-urlencoded'}
        }).then(function(response) {
            console.log(response.data);
            return true;
        }, function(data){
            return data;
        });
    }

    return {
        emails: emails,
        selected: selected,
        setCurrent: function(curr){
            selected = curr;
        },
        load: function(){
            $resource('/api/email/?format=json').query({},
                function success(result) {
                    emails.push.apply(emails, result);
                });
        },
        add: function(email) {
            for (var e in emails) if (emails[e].email == email) return false;
            return sendreq('add', email);
        },
        remove: function() {
            sendreq('remove', emails[selected].email);
        }
    }

})

我的 HTML 模板中的这段代码:

<div ng-repeat="e in emailService.emails">
    <input type="radio" ng-model="$parent.selected" ng-value="$index" ng-change="EmailSelected()" id="email_{{ $index }}" name="email">
    <label for="email_{{ $index }}" ng-bind='e.email'></label> <span ng-show="e.verified">Verified</span> <span ng-show="e.primary">Primary</span>
</div>
<div><button ng-disabled="primary" ng-click="emailService.remove()">Remove</button></div>
<form novalidate>
    <input class="form-control" type="email" name="email" ng-model="email" placeholder="Email">
    <input type="submit" ng-disabled="email === undefined" ng-click="emailService.add(email)" value="Add Email Address">
</form>

我想问一下,我是否正确组装了模块和模板,因为我是第一次使用 AngularJS。具体来说,我想问将整个工厂绑定到范围是否正确?此外,如果有人有更多时间,他可以查看其他代码以查看一切是否正确。随意写下关于我的代码的任何建议。
提前致谢!

4

2 回答 2

1

它总是取决于特定情况。

这种方式样板包装方法

$scope.add = (...args) => emailService.add(...args);

可以省略,以及它们在控制器规范中的测试。

另一个好处是它为标量范围属性的正确数据绑定和范围继承提供了现有对象:

<parent-scope>
  <p ng-init="emailService.selected = 0"></p>
  <child-scope>
    <p ng-init="emailService.selected = 1"></p>
    {{ emailService.selected === $parent.emailService.selected }}
  </child-scope>
</parent-scope>

如果没有emailService对象,这肯定不会按预期工作。这在不使用 controllerAs 语法时特别有用。

将服务暴露给范围没有任何问题——如果它的 API 与控制器范围匹配。如果不是这样,或者如果有太多的服务被这样滥用,这可能表明是一种反模式。

于 2016-05-13T15:09:29.610 回答
0

为什么要绑定整个服务?我认为您的代码中不需要这样做。您正在使用服务处理程序调用部分服务,没有特别需要将整个服务放在范围内。

于 2016-05-13T14:05:27.433 回答