AngularJS 1.4 指令:作用域、双向绑定和 bindToController [英] AngularJS 1.4 directives: scope, two way binding and bindToController

查看:26
本文介绍了AngularJS 1.4 指令:作用域、双向绑定和 bindToController的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

更新:代码的另一部分一定是愚蠢的.它现在可以工作了,所以 bindToController 语法很好.

Update: It must have been something stupid in another part of the code. It works now, so the bindToController syntax is fine.

我们使用的是 AngularJS 1.4,它引入了 新的使用方式bindToController 在指令中.

We are using AngularJS 1.4, which introduced a new way to use bindToController in directives.

经过大量阅读(可能还没有理解所有内容)后,我们像这样定义了指令:

After quite a bit of reading (and maybe not understanding everything), we defined our directive like this:

  .directive('mdAddress', function mdAddress() {
    var directive = {
      restrict: 'EA',
      scope: {},
      bindToController: {
        address: '='
      },
      templateUrl: 'modules/address/address.html',
      controller: AddressController,
      controllerAs: 'dir'
    };

像这样从另一个视图调用它:

Calling it from another view like this:

  <md-address address="vm.address"></md-address>

之前在视图控制器中定义过:

Having previously defined in the view controller:

  vm.address = {
    street: null,
    countryCode: null,
    cityCode: null,
    postalCode: null
  };

像这样引用指令模板中的变量:

Referencing the variables in the directive template like this:

  <md-input-container>
    <label>{{'ADDRESSNUMBER' | translate}}</label>
    <input type="number" ng-model="dir.address.streetNumber">
  </md-input-container>

我们花了 4 小时试图找出我们的指令不起作用的原因.好吧,它正在工作,但是控制器和指令之间的双向绑定没有,vm.address.street 被无可救药地设置为 null.

We spent 4h trying to figure out why our directive was not working. Well, it was working, but the two-way binding between the controller and the directive was not, vm.address.street was hopelessly set to null.

过了一会儿,我们只是尝试了旧的方式:

After a while, we just tried the old way:

  .directive('mdAddress', function mdAddress() {
    var directive = {
      restrict: 'EA',
      scope: {
        address: '='
      },
      bindToController: true,
      templateUrl: 'modules/address/address.html',
      controller: AddressController,
      controllerAs: 'dir'
    };

它神奇地起作用了.知道为什么吗?

And it magically worked. Any idea WHY?

推荐答案

更新:

感谢对这篇博文的引用,我需要更新我的回答.从 AngularJS 1.4 开始,你真的可以使用

Thanks to the reference to this blog post, I need to update my answer. Since AngularJS 1.4 it really seems, that you can use

scope: {},
bindToController: {
  variable: '='
}

这将执行(完全)与旧语法相同的事情:

which will do the (exact) same thing as the old syntax:

scope: {
  variable: '='
},
bindToController: true

AngularJS 源代码中解释这种行为的有用行:

The useful lines from the AngularJS source code to explain this behavior:

if (isObject(directive.scope)) {
  if (directive.bindToController === true) {
    bindings.bindToController = parseIsolateBindings(directive.scope,
                                                     directiveName, true);
    bindings.isolateScope = {};
  } else {
    bindings.isolateScope = parseIsolateBindings(directive.scope,
                                                 directiveName, false);
  }
}
if (isObject(directive.bindToController)) {
  bindings.bindToController =
      parseIsolateBindings(directive.bindToController, directiveName, true);
}

来源:AngularJS 1.4.0

原答案:

希望我能向您解释为什么您所经历的这种行为是正确的,以及您在哪里误解了范围绑定的概念.

Hopefully, I can explain you why this behavior you experienced is correct and where you did missunderstand the concept of scope binding there.

让我解释一下,你在第一个代码片段中做了什么:

Let me explain, what you did in your first code snippet:

.directive('mdAddress', function mdAddress() {
    var directive = {
      restrict: 'EA',
      scope: {},
      bindToController: {
        address: '='
      },
      templateUrl: 'modules/address/address.html',
      controller: AddressController,
      controllerAs: 'dir'
    };

使用 scope: {},您为 mdAddress 指令创建了一个隔离的作用域(没有任何继承).这意味着:父控制器和您的指令之间不会传递任何数据.

With scope: {}, you created an isolated scope (without any inheritance) for your mdAddress directive. That means: No data is passed between the parent controller and your directive.

考虑到这一点,关于您的第二个代码片段:

Having this in mind, regarding your second code snippet:

<md-address address="vm.address"></md-address>

vm.address 来自您的父控制器/视图将作为表达式分配给指令的地址属性,但是由于您之前定义了隔离范围,因此数据不会传递到 AddressController,因此在 bindToController 值中不可用.

vm.address from your parent controller/view will be assigned as expression to the address attribute of the directive, but as you defined an isolated scope before, the data is not passed into AddressController and therefore not available in the bindToController value.

让我们将 scope 对象定义视为将传入哪些数据",将 bindToController 视为哪些数据将在我的视图的 controllerAs 对象中可用".

Let's think of the scope object definition as the "which data will be passed in" and the bindToController as the "which data will be available in my view's controllerAs object".

那么,现在让我们看看最后一个(和工作代码片段):

So, now let's have a look at the last (and working code snippet):

.directive('mdAddress', function mdAddress() {
    var directive = {
      restrict: 'EA',
      scope: {
        address: '='
      },
      bindToController: true,
      templateUrl: 'modules/address/address.html',
      controller: AddressController,
      controllerAs: 'dir'
    };

在那里您也创建了一个独立的作用域,但这次您添加了要作为表达式传入的 address 属性.所以现在您从第二个代码段中的视图传入的 address 将在控制器的范围内可用.现在设置 bindToController: true,会将当前范围的所有属性绑定到控制器(或者更有可能是 controllerAs 对象).现在,它按您的预期工作,因为数据将传入作用域,数据将传出到控制器的模板作用域.

There you created an isolated scope, too, but this time you added the address attribute to be passed in as an expression. So now the address you passed in from the view in the second snippet will be available in the controller's scope. Setting bindToController: true now, will bind all the current scope's properties to the controller (or more likely the controllerAs object). And now, it works as you would expect, because data will be passed in to the scope and data will be passed out to the controller's template scope.

该简要概述是否有助于您更好地理解 scopebindToController 定义对象的概念?

Did that brief overview help you to better understand the concept of the scope and bindToController definition objects?

这篇关于AngularJS 1.4 指令:作用域、双向绑定和 bindToController的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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