1

編集: 単体テストを実行することができました - サービスを含むコードを別のファイルと別のモジュールに移動し、この新しいモジュールを fooBar モジュールの要件にし、各「it」ブロックが呼び出される前に導入しましたコードbeforeEach(module(<new_service_module_name))。ただし、アプリケーションはまだ実行されません。コンソールにもエラーはありません。これが残っている唯一の問題です。コントローラーの定義にグローバル スコープを使用すると、アプリケーションは動作しますが、angular.module.controller を使用すると動作しません。

app.js以下を含むファイルがあります。

'use strict';

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

app.config(['$routeProvider', function($routeProvider) {
  $routeProvider.
  when('/', {
    templateUrl: 'partials/form-view.html',
    controller: FormViewCtrl
  }).
  when('/resultDisplay', {
    templateUrl: 'partials/table-view.html',
    controller: TableViewCtrl
  }).
  otherwise({redirectTo: '/'});
}]);

app.service('searchResults', function() {
  var results = {};

  return {
    getResults: function() {
      return results;
    },
    setResults: function(resultData) {
      results = resultData;
    }
  };
});

controllers.js次を含む別のファイルがあります。

'use strict';

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

app.controller('FormViewCtrl', ['$scope', '$location', '$http', 'searchResults', 
    function ($scope, $location, $http, searchResults) {
        //Controller code
}]);

searchResults私が作成したサービスは、単純に getter メソッドと setter メソッドを持っています。上記のコントローラーは setter メソッドを使用するため、サービスが注入されます。

その結果、私のアプリケーションは実行されません! コントローラーのコードを次のようにグローバルに変更すると:

function ($scope, $location, $http, searchResults) {
    //Controller code
}

その後、アプリケーションが動作します!

また、グローバル スコープを使用すると、次の単体テスト ケースが機能します。

'use strict';

/*jasmine specs for controllers go here*/
describe('Foo Bar', function() {

    describe('FormViewCtrl', function() {
        var scope, ctrl;

        beforeEach(module('fooBar'));

        beforeEach(inject(function($rootScope, $controller) {
            scope = $rootScope.$new();
            ctrl = $controller('FormViewCtrl', {$scope: scope});
        }));
        }
        //"it" blocks
}

モジュールスコープに戻ると、エラーが発生します-
Error: Unknown provider: searchResultsProvider <- searchResults

したがって、グローバル スコープを使用すると、アプリケーションと単体テストが実行されますが、app.controller を使用すると、それらが壊れているように見えます。

私が指摘したもう 1 つのポイントは、コントローラー コードを のapp.js代わりに含めるcontrollers.jsと、アプリケーションと単体テストが再び機能し始めることです。しかし、それらを同じファイルに含めることはできません。アプリケーションと単体テストを壊さずに角度範囲でこれを実行するにはどうすればよいですか?

4

4 に答える 4

9

その道を行く必要はありません。モジュラー アプローチを使用できますが、問題は 2 番目のパラメーターにあります。

app.js には次のものがあります。

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

次に、コントローラーには次のものがあります。

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

そこで行っていることは、モジュールを 2 回定義することです。単純にアプリ モジュールにアタッチしようとしている場合は、2 番目のパラメーター (空の配列: []) を渡すことはできません。これにより、まったく新しいモジュールが作成され、最初のモジュールが上書きされます。

これが私のやり方です(大規模なAngularJSアプリを設計するためのこの記事に基づいています。

app.js:

angular.module('fooBar',['fooBar.controllers', 'fooBar.services']);
angular.module('fooBar.controllers',[]);
angular.module('fooBar.services', []);
...etc

controllers.js

angular.module('foobar.controllers') // notice the lack of second parameter
    .controller('FormViewCtrl', function($scope) {
        //controller stuffs
    });

または、非常に大規模なプロジェクトの場合、最上位モジュールをタイプ (ディレクティブ、フィルター、サービス、コントローラー) でグループ化するのではなく、機能 (すべてのパーシャルを含む) でグループ化することをお勧めします...これの理由は完全なモジュール性です- 同じ名前、新しいパーシャル、コードで新しいモジュールを作成し、それを置換としてプロジェクトにドロップすると、簡単に機能します)。

app.js

angular.module('fooBar',['fooBar.formView', 'fooBar.otherView']);
angular.module('fooBar.formView',[]);
angular.module('fooBar.otherView', []);
...etc

次に、formViewWeb ルートにぶら下がっているフォルダーで、次のようなタイプに基づいてファイルを分離します。

formView.directives
formView.controllers
formView.services
formView.filters

And then, in each of those files, you open with: 

angular.module('formView')
    .controller('formViewCtrl', function($scope) {

angular.module('formView')
    .factory('Service', function() {

etc etc

HTH

于 2013-05-18T16:28:09.503 に答える
2

わかりました-ようやくわかりました。app.js基本的に、グローバル スコープではなくモジュール スコープを使用する場合は、次の手順を実行する必要があります (およびのような設定がある場合controllers.js)。

  1. app.js で、モジュール スコープを定義します。

    var myApp = angular.module(<module_name>, [<dependencies>]);

  2. controllers.js では、myApp を再度定義しないでください。代わりに、次のように直接使用してください。

    myApp.controller(..);

これで問題は解決しました。アプリケーションと単体テストが正しく機能するようになりました。

于 2013-04-14T09:00:16.467 に答える
1

ベスト プラクティスは、アプリを 1 つのグローバル変数のみに設定し、必要なすべてのモジュール機能をそれにアタッチして、アプリが次のコマンドで開始されるようにすることです。

var app = angular.module('app',[ /* Dependencies */ ]);

controller.js で、新しい変数に再度開始し、以前にアタッチしたすべてのサービスと構成を失い、アプリ変数を 1 回だけ開始します。もう一度実行すると、アタッチしたサービスが失われます

次に、サービスを追加します(工場出荷時バージョン)

app.factory('NewLogic',[ /* Dependencies */ , function(  /* Dependencies */ ) {
return {
function1: function(){
   /* function1 code */

    }
  }
}]);

コントローラー用

app.controller('NewController',[ '$scope' /* Dependencies */ , function( $scope /* Dependencies */ ) {
$scope.function1 = function(){
   /* function1 code */
    };
  }
}]);

1 つのアプリ モジュールを作成し、必要なすべてのコントローラー、ディレクティブ、およびサービスをそれにアタッチしますが、すべて親アプリ モジュール変数内に含まれます。

javascriptの場合、グローバル変数を1つだけ持つのがベストプラクティスであるため、angularjsアーキテクチャがその要件を実際にうまく満たすことを何度も読みました。

ああ、依存関係の配列ラッパーは実際には必要ありませんが、JSを縮小したい場合はグローバル変数の混乱を引き起こし、アプリを完全に壊します。

于 2013-06-24T15:04:35.630 に答える