如何通过AngularJs中的隔离范围通过多个指令绑定ngModel?

时间:2014-04-09 04:52:39

标签: javascript angularjs angularjs-directive angularjs-scope

我试图通过ngModel绑定一个属性,在3层深度的指令层中。这样就可以了,除了中间级别包含ng-if,我相信它会创建一个新的范围。此时绑定已丢失。

我创建了一个jsfiddle来解释这种情况: http://jsfiddle.net/5fmck/2/

请注意,如果删除了ng-if指令,它会有效,但出于性能原因,我使用的是ng-if而不是ng-show

有没有人知道如何从小提琴中的'inputDirective'模板更新原始ngModel?

2 个答案:

答案 0 :(得分:5)

简单:3

请记住,创建了子范围=使用对$ parent的引用:)

<div ng-if='someCondition'>
    <span>In Wrapper</span>
    <input-directive ng-model='$parent.ngModel'></input-directive>
</div>

http://jsfiddle.net/5fmck/3/

// upd

据我所知,只有当ngModel是原始的而不是对象时才需要使用$ parent的引用。

答案 1 :(得分:0)

我怀疑这是由于范围如何从彼此继承的性质,因此您应该使用范围上的对象,而不是基元,并且如果要使用它们,则始终通过属性将对象传递给指令在另一个范围内。所以而不是:

$scope.test = "test";

<wrapper-directive ng-model="test" some-condition="true">

使用:

$scope.userInput = {
  test: "Test"
}

<wrapper-directive user-input="userInput" some-condition="true"> 

可以在http://jsfiddle.net/4RBaN/1/看到(我也将ngModel中的所有一个更改为另一个自定义属性,就好像你没有使用ngModel特定的东西,比如ngModelController,或者与ngForm集成) ,那我觉得KISS更好。

原因是如果父/子关系中有2个范围(通过原型继承),例如ngIf创建的范围,如果执行(或者如果Angular执行):

$parentScope.test = 'test';
$childScope.test = 'My new value';

然后$parentScope.test仍将等于'test'。但是,如果您使用对象:

$parentScope.userInput = {test: 'test'}
$childScope.userInput.test = 'My new value';

然后$parentScope.userInput.test将等于'My new value'

Angular的原始作者(我认为是)的标准引用是“如果你的模型中没有一个点,你做错了”。关于此,还有其他问题,例如If you are not using a .(dot) in your AngularJS models you are doing it wrong?

编辑:如果你确实想使用ng-model,并且总是将一个原语传递给指令而不是一个对象,那么有一种方法允许这样做。你需要:

  • 始终确保在每个指令中传递给ngModel的模型中都有一个点。因此,每个指令都需要在其控制器(或链接函数)的作用域上创建一个新对象。因此,“中间”指令的模板将是:

    <input-directive ng-model='userInput.test'>
    

    在其控制器中:

    $scope.userInput = {
      test: $scope.ngModel   
    }
    

    其中ngModel绑定到指令属性中指定的值:

    "scope" : {
      "ngModel" : "="
    }
    
  • 在每个指令中设置手动观察者,以便从内部指令对模型的更改传播回链中:

    $scope.$watch('userInput.test', function(newTest) {
      $scope.ngModel = newTest;    
    });
    

可以在http://jsfiddle.net/zT9sD/看到。我不得不说,感觉有点复杂,所以我不太确定我能推荐它。尽管如此(在我看来)比使用$parent更好,因为随着事情变得更复杂,引入新范围很容易发生,然后你将不得不使用像$parent.$parent这样的东西。