0

我创建了一个具有以下结构的角度应用程序。应用程序配置、路由、指令、控制器和过滤器都在 index.js 中定义(我知道不推荐这样做)。我所有的通用功能都在一个名为 main.js 的控制器中,这也是我在 index.html 的主视图中使用的控制器。从那时起,该应用程序由 10 个不同的视图组成,每个视图都有自己的控制器。

main.js 变得非常难以维护,所以我想将它分成五个外部“实用程序”样式文件,其中包含应用程序使用的一般功能。这些函数都使用 angular 的 $scope 并且必须能够被应用程序中存在的所有视图和控制器访问。

在过去的几天里,我尝试了几种不同的方法,例如在 Angular 的工厂服务下定义函数,使用 Angular 的 $provide 方法,定义没有视图的控制器等等。他们都没有为我工作。在不更改函数本身的任何代码的情况下,将main.js 中存在的函数分离到外部 js 文件的最简单方法是什么。让我们假设函数不能变成指令。

示例 - 检查用户名中的“guest”字符串并返回图像的函数

main.js -

$scope.defaultpic = function(username) {
        var guest = username;
        if (guest.indexOf("guest") != -1){
            {return {"background-image": "url('data:image/png;base64,chars"}}
        }
    }

在视图中

<img ng-style="defaultpic(JSON.Value)" class="user_pic" ng-src="getprofilepic/{{JSON.Value}}"/>

干杯,吉顿

4

2 回答 2

1

为了在标记中使用该函数,您仍然必须将其绑定到范围。但是,您可以将函数的主体移动到服务中:

angular.module('myapp').factory('picService',[ function () {
    return {
        defaultpic: function(username) {
            var guest = username;
            if (guest.indexOf("guest") != -1){
                {return {"background-image": "url('data:image/png;base64,chars"}}
            }
        }
    };
}]);

然后在控制器中绑定它:

$scope.defaultpic = picService.defaultpic;
于 2013-10-21T13:40:47.167 回答
1

将控制器功能重构为在不同文件中声明的服务

正如您正确指出的那样,重构功能的一个好方法是将它们放入不同的服务中。

根据角度服务文档

Angular 服务是执行 Web 应用程序常见的特定任务的单例对象或函数。

这是一个例子:

原始代码

在这里,我们有一个简单的 Hello World 应用程序,其控制器具有两个功能:greet()getName().

应用程序.js

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope) {
  $scope.getName = function () {
    return 'World';
  }

  $scope.greet = function (name) {
    return 'Hello ' + name;
  };
});

索引.html

...
<div id="container" ng-controller="MainCtrl">
  <h1>{{greet(getName())}}</h1>
</div>
...

我们想测试我们的作用域是否总是具有这两个功能,所以我们知道它按预期工作,所以我们将编写两个简单的 jasmine 测试:

appSpec.js

describe('Testing a Hello World controller', function() {
  var $scope = null;
  var ctrl = null;

  //you need to indicate your module in a test
  beforeEach(module('plunker'));

  beforeEach(inject(function($rootScope, $controller) {
    $scope = $rootScope.$new();

    ctrl = $controller('MainCtrl', {
      $scope: $scope
    });
  }));

  it('should say hallo to the World', function() {
    expect($scope.getName()).toEqual('World');
  });

  it('shuld greet the correct person', function () {
    expect($scope.greet('Jon Snow')).toEqual('Hello Jon Snow');
  })
});

在 plnkr 中查看

第 1 步:将控制器功能重构为单独的功能

为了开始将控制器与函数解耦,我们将在 app.js 中创建两个单独的函数。

应用程序.js

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope) {
  $scope.getName = getName;

  $scope.greet = greet;
});

function getName() {
  return 'World';
}

function greet(name) {
  return 'Hello ' + name;
}

现在我们检查我们的测试输出,我们看到一切正常。

查看第 1 步的 plnkr

第 2 步:将功能移动到自己的服务中

我们将定义一个 NameService 和 GreetService,将我们的函数放入其中,然后在我们的控制器中将服务定义为依赖项。

应用程序.js

var app = angular.module('plunker', []);

app.service('NameService', function () {
  this.getName = function getName() {
    return 'World';
  };
});

app.service('GreetService', function() {
  this.greet = function greet(name) {
    return 'Hello ' + name;
  }
});

app.controller('MainCtrl', ['$scope', 'NameService', 'GreetService', function($scope, NameService, GreetService) {
  $scope.getName = NameService.getName;

  $scope.greet = GreetService.greet;
}]);

我们确保我们的测试仍然是绿色的,所以我们可以继续进行最后一步。

看看 plunker 中的第 2 步

最后一步:将我们的服务放在不同的文件中

最后,我们将创建两个文件 NameService.js 和 GreetService.js 并将我们的服务放入其中。

名称服务.js

angular.module('plunker').service('NameService', function () {
  this.getName = function getName() {
    return 'World';
  };
});

问候服务.js

angular.module('plunker').service('GreetService', function() {
  this.greet = function greet(name) {
    return 'Hello ' + name;
  }
});

我们还需要确保将新脚本添加到我们的 index.html

索引.html

...
<script src="NameService.js"></script>
<script src="GreetService.js"></script>
...

这就是我们的控制器现在的样子,整洁吧?

应用程序.js

var app = angular.module('plunker', []);

app.controller('MainCtrl', ['$scope', 'NameService', 'GreetService', function($scope, NameService, GreetService) {
  $scope.getName = NameService.getName;

  $scope.greet = GreetService.greet;
}]);

最后一步。

就是这样!我们的测试仍然通过,所以我们知道一切都像一个魅力。

于 2013-10-21T15:56:25.153 回答