双向绑定不工作的指导与transcluded范围 [英] Two way binding not working in directive with transcluded scope

查看:112
本文介绍了双向绑定不工作的指导与transcluded范围的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我这势必模型名称控制器已经一个文本框。有控制器内部指令并有指令内的另一个文本框被绑定到相同型号名称

I've a textbox in a controller which is bound to model name. There's a directive inside the controller and there's another textbox inside the directive which is bound to the same model name:

<div class="border" ng-controller="editCtrl">
   Controller: editCtrl <br/>
   <input type="text" ng-model="name" />
   <br/>
   <tabs>
      Directive: tabs <br/>
      <input type="text" ng-model="name"/>
   </tabs>
</div>

mod.directive('tabs', function() {
  return {
    restrict: 'E',
    transclude: true, 
    template:
      '<div class="border" ng-transclude></div>',
  };
});

当您在文本框外它反映在内部文本框输入一些东西,但如果你在内部文本框中键入一些它停止工作,即两个文本没有更多的反映了相同的值。

When you type something in the outer textbox it's reflected in the inner textbox but if you type something in the inner textbox it stops working i.e. both textbox no more reflects the same value.

参见例如: http://jsfiddle.net/uzairfarooq/MNBLd/

我采用双向绑定ATTR也试过(范围:{名称:'='} ),但它给语法使用范围:{名称:'@'} 有同样的效果。

I've also tried using two way binding attr (scope: {name: '='}) but it gives syntax error.And using scope: {name: '@'} has same effect.

任何帮助将大大AP preciated。

Any help would be greatly appreciated.

除了公认的答案,这篇文章真帮助我理解儿童scpoes原型继承。我强烈建议有任何问题与范围来仔细阅读。

In addition to the accepted answer, this article really helped me in understanding the prototypical inheritance in child scpoes. I'd highly recommend anyone having problem with scopes to read it thoroughly.

推荐答案

A指令transclude:真正的导致指令创建一个新的(transcluded)子范围。这个新的范围中典型从父继承的范围。在你的情况,父范围与editCtrl控制器关联的范围。

A directive with transclude: true results in the directive creating a new (transcluded) child scope. This new scope prototypically inherits from the parent scope. In your case, the parent scope is the scope associated with the editCtrl controller.

在孩子的范围(即,NG-模式)使用双向数据绑定绑定到持有原始值父作用域属性(例如,名称)总是导致问题 - 好吧,我应该说,预期这是行不通的。当作用域属性中的孩子被改变(例如,键入到第二个文本框)的孩子创建一个隐藏/阴影的同名父作用域属性一个新的作用域属性。如果父属性包含一个原始值,这个值是(本质)复制到子类属性的在创建子属性时的。在子范围(例如,第二个文本框)未来的变化只是影响孩子属性。

Using two-way databinding in a child scope (i.e., ng-model) to bind to a parent scope property that holds a primitive value (e.g., name) always causes problems -- well, I should say that it doesn't work as expected. When the scope property is changed in the child (e.g., you type into the second textbox) the child creates a new scope property that hides/shadows the parent scope property of the same name. If the parent property holds a primitive value, that value is (essentially) copied to the child property when the child property is created. Future changes in the child scope (e.g., the second textbox) only affect the child property.

输入到第二个文本框(即财产是孩子改变之前),儿童/ transcluded范围发现在通过原型父范围名称属性继承(在下面图象的虚线)。这就是为什么两个文本框最初保持同步。下面,如果键入标记到第一个文本框,这是示波器的样子:

Before typing into the second textbox (i.e., before the property is changed in the child), the child/transcluded scope finds the name property in the parent scope via prototypal inheritance (dashed line in picture below). This is why the two textboxes initially remain in synch. Below, if you type "Mark" into the first text box, this is what the scopes look like:

我创建了一个小提琴在那里你可以检查两个范围。点击进入输入第二个文本框前,旁边的第二个文本框显示范围链接。这将让你看到transcluded子范围。你会发现,它并没有在这一点上有一个名称属性。清除控制台,输入到第二个文本框,然后再次单击该链接。你会发现,孩子现在的范围有一个名称属性和初始值是parent属性有(标记)的值。如果键入喜欢角到第二个文本框,这是个什么范围如下:

I created a fiddle where you can examine the two scopes. Click the "show scope" link next to the second textbox before typing into the second textbox. This will allow you to see the transcluded child scope. You will notice that it does not have a name property at this point. Clear the console, type into the second text box, then click the link again. You will notice that the child scope now has a name property, and the initial value was the value that parent property had ("Mark"). If you typed " likes Angular" into the second text box, this is what the scopes look like:

有两种解决方法:


  1. 请@ pgreen2暗示什么(这是最佳实践的解决方案) - 使用一个对象,而不是原始的。当使用一个对象,孩子/ transcluded范围没有得到一个新的属性。只有原型继承是在这里打球。在下面的图片,承担editCtrl的$范围定义了这个对象:结果 $ scope.myObject = {名:马克,anotherProp:...}
    结果

  2. 在子范围内使用$父(这是一个脆弱的解决方案,不推荐,因为它使有关HTML结构假设):使用 NG-模式=$ parent.name的&lt内;输入>这是在&lt之内;标签>元素。上面第一张图片显示了这一过程。

  1. do what @pgreen2 suggests (this is the "best practice" solution) -- use an object instead of a primitive. When an object is used, the child/transcluded scope does not get a new property. Only prototypal inheritance is in play here. In the picture below, assume the editCtrl's $scope has this object defined:
    $scope.myObject = { name: "Mark", anotherProp: ... }:
  2. use $parent in the child scope (this is a fragile solution, and not recommended, as it makes assumptions about HTML structure): use ng-model="$parent.name" inside the <input> that is within the <tabs> element. The first picture above shows how this works.

使用范围时发生语法错误不允许 - 即,{{}},不能使用。取而代之的&LT;标签名称={{名}}&GT; 使用&LT;标签名称=名字&GT;

使用@的工作原理相同,transclude情况,因为NG-transclude使用transcluded范围,而不是通过使用范围内创建的分离范围:{...}

Using '@' works the same as the transclude case because ng-transclude uses the transcluded scope, not the isolate scope that is created by using scope: { ... }.

有关(地段)有关作用域的详细信息(包括图片)看到结果<一个href=\"http://stackoverflow.com/questions/14049480/what-are-the-nuances-of-scope-prototypal-prototypical-inheritance-in-angularjs/14049482\">What范围是原型/原型继承的细微差别AngularJS?

For (lots) more information about scopes (including pictures) see
What are the nuances of scope prototypal / prototypical inheritance in AngularJS?

这篇关于双向绑定不工作的指导与transcluded范围的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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