2013-10-21 27 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.

就是這樣!我們的測試仍然通過,所以我們知道一切都像魅力一樣。