了解Angular.js控制器参数

时间:2013-10-08 02:40:35

标签: angularjs

我刚开始学习Angular.js,我一直在关注project.js in the "Wire up a Backend" example on the Angular home page

我对控制器功能中的参数感到困惑:

function ListCtrl($scope, Projects) {
  ... 
}   

function CreateCtrl($scope, $location, $timeout, Projects) {
  ... 
}

function EditCtrl($scope, $location, $routeParams, angularFire, fbURL) {
   angularFire(fbURL + $routeParams.projectId, $scope, 'remote', {}).
   then(function() {
     ...
   });
}  

这些控制器函数在routeProvider中调用,但没有给出任何参数。

$routeProvider.
  when('/', {controller:ListCtrl, templateUrl:'list.html'}).
  when('/edit/:projectId', {controller:EditCtrl, templateUrl:'detail.html'}).
  when('/new', {controller:CreateCtrl, templateUrl:'detail.html'}).
  otherwise({redirectTo:'/'});
});

到目前为止,我唯一能找到的可能是"Injecting Services Into Controllers"解释的是$location$timeout,而不是参数方法angularFire和{{1 }}

我的具体问题是:

  1. 控制器参数可以是什么?

  2. 使用参数调用控制器函数在哪里?或者参数没有被调用,但只是与控制器关联的东西,其中关联发生了很多Angular.js魔法(如果是这样,我可以在github上看到源代码)吗?

  3. fbURL定义在哪里?

  4. 参数中的angularFire如何链接到:

    fbURL
  5. 是否有我可以看到所有服务的地方,例如Angular.js提供的angular.module('project', ['firebase']). value('fbURL', 'https://angularjs-projects.firebaseio.com/'). factory ... $location? (我试图找到列表但失败了。)

4 个答案:

答案 0 :(得分:143)

  • 控制器参数可以是什么?

    控制器参数是依赖,AngularJS注入服务注入。它们可以是任何东西。但它们通常是将在控制器内部使用的服务

  • 使用参数调用控制器函数在哪里?

    AngularJS中的控制器,指令,过滤器,服务和许多其他东西都是函数。但是该框架管理了许多 如何这些函数被调用。

    您所谓的相关内容有一个名称:依赖,如上所述。您所谓的 magic 是AngularJS 依赖注入机制。

    当注入器调用这些函数(控制器和其他函数)时,它会读取参数名称(例如:$scope$httpangularFire)并搜索已注册的服务使用该名称,然后在调用函数时将其作为参数提供。

    很简单。您可以通过多种方式来指导您的"依赖关系" (由喷射器管理的参数)到喷射器。

    当您将函数声明为function myCtrl($scope) {}时,注入器将能够从参数名称中找到$scope服务。但是如果您缩小 JavaScript代码,则注入器将无法再找到该服务,因为参数名称将被修改为更小的字符串,例如" a"或" x"。为避免此问题,可以使用数组表示法指定要注入的服务名称。在这种情况下,您可以声明您的函数:myCtrl = ['$scope', function($scope) {}]

    你会在AngularJS世界中看到很多数组符号用法。现在你开始明白了。你甚至可以注入$scopeangularFire并在你的函数中使用其他名称(更改名称不推荐 - 此示例来自此处出于学习目的):['$scope', 'angularFire', function(skop, af) {}] - 这样,在函数内部你可以使用$ scope作为" skop"和angularFire as" af"。数组中服务的顺序与参数的顺序相匹配。

另一个例子:

var myController = ['$scope', '$resource', '$timeout',
    function($scope, $resource, $timeout) {
        // this controller uses $scope, $resource and $timeout
        // the parameters are the dependencies to be injected
        // by AngularJS dependency injection mechanism
    }
];
  • angularFire定义在哪里?

    firebase 模块

    正如您现在已经知道的那样,只要注射器具有该物质,注射器就会注射任何物质。 名称已在其记录中注册并提供。如果有"服务"使用名称,他能够提供

    如何构建注入器使用的name => stuff列表?

    模块就是答案。 模块只是name => stuff的列表。它位于模块中,您可以在其中注册服务,工厂,过滤器,指令等。

    仔细查看Module methods at the official documentation ...几乎所有人都会收到参数:名称和一些&#34; 内容&#34; (其中&#34; stuff&#34;几乎总是功能,定义控制器,工厂或指令)。这就是所有这些&#34;东西&#34;它将通过指定的名称 <注入

    AngularJS服务,如&#34; $ timeout&#34;,&#34; $ http&#34;默认情况下可以使用其他功能,因为框架已经加载了 ng模块

    对于其他服务,您需要加载/需要模块。这就是你用 ngRouter firebase 等做的事情......通过加载模块,它的注册资料是可在您的模块/应用

  • 中进行注射

让我们看一个循序渐进的例子:

// An empty module:
var module = angular.module('myModule', []);

// Now, adding an "injectable" constant: 
module.constant('niceStuff', { blip: 'blop', blup: 307 });

// We could add a service:
module.service('entityManager', ['$http', function($http){  }]);

// and so on... if I wanted to use "$resource" instead of "$http"
// in the entityManager service above...
// ...I would need to require the ngResource when creating the module above,
// like this: var module = angular.module('myModule', ['ngResource']);
// because "$resource" is not available by default

// NOW, anywhere else, since the code above already ran
// I can use those NAMES as dependencies like this:

// We are creating another module now:
var koolModule = angular.module('km', ['myModule']);
// Note that I am requiring the previous module through its registered name

// Now, anything I've declared in that module
// - just like "ng" (by default) and "firebase" (required) does -
// is available for "injection"!!!

koolModule.controller('koolController',
    ['niceStuff', 'entityManager', function(niceStuff, entityManager) {
        console.log(niceStuff.blip);      // 'blop'
        console.log(niceStuff.blup + 10); // 317
    }]
);

这就像angularFire这样的firebase东西变得可用了!我们做了什么?首先,我们创建了&#34; myModule&#34;,并向其注册了NAMED内容。后来,我们需要&#34; myModule&#34;为我们的&#34; koolModule&#34; - 这些NAMES已经在注射器name => stuff列表中可用。

  • 参数中的fbURL如何链接

    正如我们刚刚看到的那样,大多数模块方法只是注册事物 - 为事物提供名称以便注入和/或稍后通过这些名称使用。

    调用module.value('fbURL', 'https://angularjs-projects.firebaseio.com/')时, fbURL (和指定的值)会注册到name => stuff列表中...在这种情况下,名称为&#34; fbURL&#34;和值/ stuff是URL字符串 - 但它可以是任何东西!

  • 是否有我可以看到所有服务的地方,例如$ location和$ timeout,Angular.js提供了什么?

    是的,API参考:http://docs.angularjs.org/api/

    通过模块关注左侧导航的组织方式 ...首先, ng 模块,包含大量指令,服务,过滤器等。然后,下面是其他模块(ngRoute,ngResource,ngMock等),每个模块都包含自己的服务,装配工或指令......

感谢有机会分享这些想法。我喜欢写它们。

答案 1 :(得分:1)

根据toxaq评论,这里是评论作为答案

  1. 控制器参数可以是什么?

    它主要可以是服务,工厂,值,常量等...您在使用路径定义的解决方案之前已在某处定义。

  2. 使用参数调用控制器函数在哪里?

    以下是定义控制器的正确方法:

    angular.module('project').controller('EditCtrl', [
        '$scope', 
        '$location', 
        '$routeParams', 
        'angularFire', 
        'fbURL', 
        function($scope, $location, $routeParams, angularFire, fbURL) { 
            ... 
        } 
    ]); 
    

    这样,您首先设置要注入的服务的名称,然后根据需要为这些服务提供不同的名称。事实上,如果你想在以后最小化你的角度代码,这是必须的(因为最小化将重命名变量,角度需要仍然能够找到服务名称)。

  3. angularFire定义在哪里?

    定义项目模块时,还包括firebase模块依赖性。在firebase模块内部,必须有像之前的fbURL一样的angularFire服务。

  4. 参数中的fbURL如何链接到

    就像您似乎理解的那样,控制器的参数是通过控制器定义的角度注入的。 Angular将查看所有已注册的服务,并尝试查找与参数的指定名称匹配并注入相应的服务!

  5. 是否有我可以看到所有服务的地方,例如$ location和$ timeout,Angular.js提供了什么?

    有关Angular中包含的所有内置服务,过滤器和指令的列表,请查看API:http://docs.angularjs.org/api

答案 2 :(得分:1)

  

使用参数调用控制器函数在哪里?

使用ngController指令实例化控制器函数,或者如果您在使用$routeProvider创建路径期间提到了控制器。 AngularJS会为您进行转换,并使用DI注入您在控制器上定义的参数。

DI通过匹配参数的名称(或某些时间顺序)来工作。因此$scope将获得当前范围,$http将获得http服务

答案 3 :(得分:0)

首先选择这个框架。这是最好的。使用$符号看到的那些变量是注入的,是标准框架的一部分。这些服务将使您的生活变得更加轻松。考虑控制器的最佳方式是脚本表。它们有助于分离代码。不要将它们视为方法。您看到的那些变量,例如$ timeout&amp; $ scope是在您需要完成某些事情时会派上用场的服务。该框架的所有文档都在http://docs.angularjs.org/api/,但我将从本教程开始http://docs.angularjs.org/tutorial/

angularfire不是框架的一部分。它是另一种利用框架来创建强大的实时分布式网络的服务。当您加载angularfirejs时,它会附带服务,然后将其作为您看到的参数注入。

要回答第二个问题,只要您提供相应的服务,您传递的参数就可以是任何内容。请参考这个为控制器创建自己的参数: http://docs.angularjs.org/guide/dev_guide.services.creating_services

fbURL只是一个你可以创建的变量,你在问题中放置的代码就是如何制作它的指令。

Angularjs不是您可以通过查看它提供的内容来学习的框架类型。仅仅因为它提供了一切。你可能带来的一切都是一个很棒的应用程序。相反,你应该专注于要求谷歌如何用角度来解决你的问题。

另请查看youtube上的视频。你会发现一些很棒的。