从教程中澄清AngularJS理论片段

时间:2016-07-03 17:40:15

标签: javascript angularjs inheritance scope

来自Step 3 of AngularJS Tutorial的伟大理论片段中,那篇文章让我想知道:

  
      
  1. 范围,粘合我们的控制器和模板   一起进入动态视图,不是与其他部分隔离开来的   页。这意味着一个随机的,无关的变化   页面的不同部分(例如属性名称冲突)可能具有   意外和难以调试的副作用对我们的看法。
  2.   

(来自同一链接的未引用的第1部分非常清楚)

我无法想象一个reallife代码示例,说明引用文本中显示的问题。你能告诉我这样一个例子吗?

我自己的猜测是基于继承的范围:

<!doctype html>
<html lang="en" ng-app="phonecatApp">
  <head>
    ...
  </head>
  <body>

    <div ng-controller="PhoneListController">

      {{secretObject.dontDareToTouchThat}} 

      <div ng-controller="PhoneListTwoController">

        <ul  ng-click="touchThat()">
          <li ng-repeat="phone in phones" >
            <span>{{phone.name}}</span>
            <p>{{phone.snippet}}</p>
          </li>
        </ul>

      </div>
    </div>

  </body>
</html>

控制器的逻辑:

'use strict';

angular.module('phonecatApp', [])
.controller('PhoneListController', function PhoneListController($scope) {

  $scope.secretObject = {
    dontDareToTouchThat: 'I"m pure and beautiful'
  }

}).controller('PhoneListTwoController', function PhoneListTwoController($scope) {

  $scope.touchThat = function(){
     $scope.secretObject.dontDareToTouchThat = 'Derp';
  }

  $scope.phones = [ ... ];
});

但我完全不确定,因为PhoneListTwoController的可能行为看起来不像“页面不同部分的随机,无关的变化”。一个范围在另一个范围内,操纵外部范围,我认为作者意味着不同的东西,比如两个兄弟范围相互混淆。

所以,再次,我请你用相关的代码示例说明引用的段落。

3 个答案:

答案 0 :(得分:1)

该段落由Georgios Kalpakas添加为commit #c2033d7 on May 24

您可能想问他一个问题。

答案 1 :(得分:1)

这篇教程可能会在这里夸大一点。至少它并不是非常精确。

我创建了一个simple example on plunker,它显示了哪种干扰是可能的,哪些不是干扰。

ng-controller指令确实会创建一个新的子范围。范围上的变量由子范围原型继承。

参考plunker example这意味着由控制器1定义的$ scope.someVariable对控制器2定义的$ scope.someVariable没有任何影响 - (控制器1既不是控制器2的祖先也不是后代)。它还意味着为$ scope.someVariable设置的值不能被其父控制器覆盖,该控制器在其作用域上设置相同的变量。控制器3也是父控制器的后代,它本身不设置$ scope.someVariable。在这种情况下,plunker显示父控制器设置的值在控制器3控制的视图片段中生效。在父控制器范围的所有子范围内,someVariable将作为
   Object.getPrototypeOf($scope).someVariable

尽管如此,我同意这个教程,使用将其状态绑定到其控制器实例的组件(在模板中称为$ ctrl)而不是直接使用范围有很多优点。组件具有明确的导入和导出模型。这使它们可以互换并增加了重复使用的机会。

答案 2 :(得分:1)

这确实是指范围继承及其(通常不是直接的)后果。如果你还没有看到它,这是一篇很好的文章:Understanding Scopes

它比你想象的要复杂得多:) 特别是(如教程中所提到的)适用于大型真实世界的应用程序,其中不同的团队在应用程序的不同部分工作,或者某些部分在几个月内保持不变。

要展示一个非常简单的“现实主义”示例(这也不像大型应用程序那么复杂):

想象一下,你正在创办自己的事业;一个电子商店。你想从小做起,所以你现在只有手机和平板电脑。

您只需要一个基本布局 - 标题,导航栏和您的内容区域:

My Cool e-Shop
----------------------------
[Phones]   [Tablets]
----------------------------

<CONTENT HERE>

您设置了两条路线 - 一条用于手机,一条用于平板电脑 - 并决定将每个网页的内容封装为类似组件的指令。例如。 #/phones路由将包含<phone-list></phone-list>这样的模板,phoneList指令将如下所示(遗憾的是您从未听说过隔离范围):

.directive('phoneList', function phoneListDirective() {
  // DDO
  return {
    template:
        '<h2>Phones</h2>' +
        '<ol>' +
          '<li ng-repeat="phone in phones">' +
            '<b>{{ phone.name }}</b> (OS: {{ phone.os }})' +
          '</li>' +
        '</ol>',
    scope: true,
    link: phoneListPostLink
  };

  // Functions - Definitions
  function phoneListPostLink(scope) {
    scope.phones = [
      {id: 1, name: 'Samsung Galaxy', os: 'Android'},
      {id: 2, name: 'Google Nexus', os: 'Android'},
      {id: 3, name: 'Nokia Lumia', os: 'Windows'},
      {id: 4, name: 'Apple iPhone', os: 'iOS'}
    ];
  }
})

到目前为止,这么好。平板电脑的路线和指令几乎相同,一切正常。

很快,您的可用手机和平板电脑列表就会增长,您需要添加filter功能。小菜一碟,您只需将以下代码段添加到指令的模板中:

<div>
  Filter:
  <input type="search" ng-model="search.name" placeholder="Name..." />
  <input type="search" ng-model="search.os" placeholder="OS..." />
</div>
<li ng-repeat="phone in phones | filter:search">

就这么简单,您的用户可以按名称和操作系统搜索手机和平板电脑。生意很好,生活很好。

快进几个月,您的网站也在增长,其中包含更多部分和产品类别。您决定“全局搜索”小部件将是导航栏的一个很好的补充。您需要做的就是将以下代码段添加到主模板中:

<div class="search-widget">
  <input type="search" ng-model="query" placeholder="Search the entire site..." />
  <button ng-click="search(query)" ng-disabled="!query">Search</button>
</div>

(当然,在主控制器上实现$scope.search()方法......)

其余的是历史:P
在您知道之前,销售很快就会开始下降并且您已经停业。

这是一个简单的POC,可以在实践中看到这一点:Demo

<强> TL;博士
使用隔离范围和利润!