传递给控制器​​的$ scope和传递给指令的$ scope之间的区别和关系 [英] The difference and relationship between the $scope passed in a controller, and the $scope passed in a directive

查看:81
本文介绍了传递给控制器​​的$ scope和传递给指令的$ scope之间的区别和关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

controller中传递的$scopedirective中传递的$scope有什么区别和关系?

What is the difference and relationship between the $scope passed in a controller, and the $scope passed in a directive?

您将如何设置它们?

推荐答案

这是对controller中传递的$scope与传递的$scope之间的区别和关系的简要说明.在directive中是:

This is a brief explanation of what is the difference and relationship between the $scope passed in a controller, and the $scope passed in a directive is:

从下面的基本Angular设置中可以看到,$scope既传递给Angular Controller,又传递给Angular Directive.但是有什么区别,这些$scope如何相互关联和交互?

As you can see form the basic Angular setup below, $scope is passed to both the Angular Controller and to the Angular Directive. But what are the differences, and how do these $scopes relate and interact with each other?

基本角度设置

Angular应用:

angular.module('app', []);

角度控制器:

angular.module('app').controller('mainCtrl', function($scope) {
  $scope.user = {
    name: 'Luke Skywalker',
    address: {
      street: 'PO Box 123',
      city: 'Secret Rebel Base',
      planet: 'Yavin 4'
    },
    friends: [
      'Han',
      'Leia',
      'Chewbacca'
    ]
  }
});

角度指令:

angular.module('app').directive('userInfoCard', function() {
  return {
    templateUrl: "userInfoCard.html",
    restrict: "E",
    controller: function($scope) {
      $scope.knightMe = function(user) {
        user.rank = "knight";
      }
    }
  }
});

可以使用3种方法来设置directive scope和包含的controller scope之间的关系:

There are 3 ways you can set up the relationship between the directive scope and the containing controller scope:

默认设置是directive与包含controller的范围 共享 .此图说明了这种关系.

The default is for the directive to share the scope with the containing controller. This diagram illustrates this relationship.

指令范围-共享

您可以看到紫色的父级$scope,我们可以看到在父级Controller上创建的User object.具有共享$ scope的指令完全位于父级controller's $scope中,并且可以访问父级controller $scope上的每个对象.

You can see the parent $scope in purple, and we can see our User object created on the Parent Controller. The directive with the shared $scope lives entirely in the parent controller's $scope, and it has access to every object on the parent's controller $scope.

如果指令必须修改$ scope或将项目添加到$ scope,它将属于parent controller's $scope而不是directive.如果您必须在controllerdirective上添加一行以注销$scope (console.log($scope);,则可以轻松地看到这一点.您会注意到,两个 ChildScopes $ id 都是相同的.

If the directive had to modify or add items to the $scope, it would belong to the parent controller's $scope and not the directive. You can easily see this if you had to add a line to the controller and the directive to log out the $scope (console.log($scope);). You will note the $id of both ChildScopes would be the same.

共享范围是处理directives$scope的最简单方法.

Shared Scope is the simplest way to deal with $scope in directives.

指令继承范围

下图说明了directive继承的$scope:

图1

我们再次在控制器$ scope中创建了一个用户对象,但将指令设置为继承了$ scope.

We once again have a user object created in the controller $scope, but with the directive set up to have inherited $scope.

当我们在directive $scope中创建新项目时,它将变为内部数据,并且对父级$scope不可见.换句话说,该项目将驻留在directive $scope上,而不是在父$scope上.

When we create a new item in the directive $scope, it will become Internal Data, and not visible to the parent $scope. In other words that item will live on the directive $scope and not on the parent $scope.

请参见下面的图2 :

图2

您要这样做的原因有很多,最常见的是将directive中的数据封装.

There are several reasons why you would want to do this, the most common would be to encapsulate the data inside the directive.

要创建具有继承的$scope的指令,请在指令中添加scope property并将其设置为true(将其设置为false将被共享$scope-这是在任何情况下都是默认值.

To create a directive with inherited $scope, you add a scope property to the directive, and set it to true (setting it to false would be shared $scope - which is the default in any case).

请参见下面的directive代码:

角度指令:

angular.module('app').directive('userInfoCard', function() {
  return {
    templateUrl: "userInfoCard.html",
    restrict: "E",
    scope: true,
    controller: function($scope) {
      $scope.knightMe = function(user) {
        user.rank = "knight";
      }
    }
  }
});

通过控制台注销时,您会注意到像以前一样有2个ChildScope对象.但是这次,每个$scope对象的 $ id 不同.

When you log this out via the console, you will notice 2 ChildScope objects as before. But this time the $id is different for each $scope object.

需要注意的一点:directive ChildScope对象具有一个名为 $ parent 的属性.它与controller ChildScope对象具有相同的 $ id .因此,包含的controller $scope已被设置为directive $scope $ parent .您还将注意到用户对象在父级 $scope中可见.这是真正的JavaScript 继承.

One thing to note: the directive ChildScope object has a property called $parent. This has the same $id as the controller ChildScope object. So the containing controller $scope has been set as the $parent of the directive $scope. You will also note the user object is visible in the parent $scope. This is true JavaScript inheritance.

注意:您将注意到指令ChildScope对象具有原型(_proto_).当您查看原型时,您会发现这也是该指令的同一作用域对象,从而实现了真正的继承.

Note: You will notice that the directive ChildScope object has a prototype (_proto_). When you look at the prototype, you can see that this is also that same scope object of the directive, making this true inheritance.

阅读:

https://developer.mozilla.org/en/docs/Web/JavaScript/Inheritance_and_the_prototype_chain

http://javascript.info/tutorial/inheritance

此处的主要区别不是子范围在父范围上可以看到的内容,而是子范围创建新数据时发生的情况.此数据在子作用域内部,而对父作用域不可见.

隔离范围

下图说明了这种情况:

再一次,我们有一个包含 user 对象的父controller $scope.与继承的 $scope一样,在directive $scope中创建的数据将对内部和不可见 > $scope.

Once again we have a parent controller $scope that contains a user object. And as with inherited $scope, the data created in the directive $scope will be internal and not visible to the controller $scope.

但是我们遇到的问题是directive $scope无法看到controller $scope上的数据.通常,我们希望看到controller $scope的某些数据元素.

But we have the issue of the directive $scope not being able to see the data on the controller $scope. Often we would want to see certain data elements of the controller $scope.

为解决这个问题,您可以在逐个对象的基础上,在隔离的$scope和父级$scope之间创建特殊的绑定.这样,孤立的$scope不能看到父级$scope上的所有内容,但是可以看到您看到的特定项目.

To solve this you can create a special binding between the isolated $scope and the parent $scope on an object by object basis. This way the isolated $scope cannot see everything on the parent $scope, but it can see specific items you make visible.

为此,请将 scope 属性上的 true 更改为对象{} .

To do this, you change the true on the scope property to an object {}.

如果必须将此登录到控制台,您将再次看到每个ChildScope对象都有其自己的唯一 $ id .您还将注意到,子作用域(directive)仍然具有 $ parent 对象,该对象是父作用域(controller),但是这次没有父作用域链接到原型.

If you had to log this to the console, you would see once again that each ChildScope objects has its own unique $id. You will also note that the child scope (directive) still has a $parent object that is the parent scope (controller), but this time there is no parent scope linked to the prototype.

要使controller user 对象在directive的范围内可见,可以向"user"的指令范围对象添加一个属性,并将其值设置为"=",告诉作用域期望使用"user"的值将对象传递给该对象.

To make the user object of the controller visible to the scope of the directive, you can add a property to the directive scope object of "user", and set its value to "=", telling the scope to expect an object to be passed to it with the value of "user".

下面的代码演示了这一点:

angular.module('app').directive('userInfoCard', function() {
  return {
    templateUrl: "userInfoCard.html",
    restrict: "E",
    scope: {
      user: '='
    },
    controller: function($scope) {
      $scope.collapsed = ($scope.initialCollapsed === 'true');
      $scope.knightMe = function(user) {
        user.rank = "knight";
      }
      $scope.collapse = function() {
        $scope.collapsed = !$scope.collapsed;
      }
    }
  }
});

这是在directive范围和包含的controller范围之间建立关系的三种方法.

And that is the 3 ways to set up the relationship between the directive scope and the containing controller scope.

特别感谢Joe Eames. https://github.com/joeeames

A special thanks to Joe Eames. https://github.com/joeeames

这篇关于传递给控制器​​的$ scope和传递给指令的$ scope之间的区别和关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆