2013-10-21 40 views
0

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

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

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

实施例 - 功能,对于 '客户' 的字符串检查用户名,并返回一个图像

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}}"/> 

干杯, 吉顿

+0

你可以添加一个需要访问范围的效用函数的例子吗?如果它真的是一个实用函数,应该可以重构它以不使用$ scope。否则它可能是一个指令的候选人。无论如何,很难说没有一个例子。 – Narretz

+0

Hi @Narretz,增加了一个例子。请不要为我提供重构代码或将其转换为指令的方式,我知道如何执行这些方法,这也不是我的问题。我想知道如何将函数移动到一个单独的js文件。 tnx – Gidon

+0

既然你不需要任何提示,那么我只是说你使用控制器的方式不是角度“最佳实践”。你可以在视图中完全编写你的例子,或者使用一个指令,甚至把函数放在一个服务中,然后把服务函数绑定到$ scope变量。不过,我不推荐它。 – Narretz

回答

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; 
+0

伟大的:)像一个魅力工程。谢谢Davin – Gidon

+0

伟大的答案Davin!我做了一个更详细的,以防止任何人查看这个答案需要一个。我希望它有助于^ _ ^ – Julian

1

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

正如你所说的,重构函数的一个好方法是把它们放到不同的服务中。

按照angular Service docs

角服务是单身对象或进行常见的web应用程序特定任务的功能。

下面是一个例子:

原始代码

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

app。JS

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

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

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

的index.html

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

我们要测试我们的范围总是有两种功能,所以我们知道它的工作如预期,所以我们要编写两个简单茉莉测试:

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'); 
    }) 
}); 

Check it out in plnkr

第1步:重构控制器功能整合到不同的功能

为了开始我们的控制器去耦我们的功能,我们将做出内部app.js.两个单独的功能

app.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; 
} 

现在我们检查我们的测试输出,我们看到,一切都可以正常使用。

Check out the plnkr for step 1

第2步:移动功能,以自己的服务

我们将定义一个名称服务和GreetService,把我们的功能他们,然后定义服务作为我们的控制器依赖。

app.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; 
}]); 

我们确保我们的测试仍然是绿色的,所以我们可以移动到最后一步。

Have a look at step 2 in plunker

最后一步:把我们的服务在不同的文件

最后,我们将两个文件,NameService.js和GreetService.js,把我们的服务在其中。

NameService.js

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

GreetService.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> 
... 

这就是我们的控制器看起来像现在一样,整洁吧?

app.js

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

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

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

Plunker for the final step.

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