AngularJS:Transclusion创建了新的范围

时间:2014-08-07 10:52:14

标签: javascript angularjs

我创建了一个使用transclusion的新指令,并将 scope 属性设置为 false (使用父作用域)。虽然它可以访问周围范围内的数据,但该指令无法更新它。

请举例here。修改第一个文本框时,将更新对文本的所有绑定,但是当更改了已转换的文本框时,仅修改同一范围内的引用。我的示例我希望两个文本框都更新对 text 的所有引用。

transclusion是否会创建新范围?这可以以某种方式被阻止吗?

示例中的代码:

HTML:

  <script type="text/ng-template" id="tmpl.html">
       <ul> 
          <li>I want to stay here</li>
      </ul>
  </script>

  <div ng-controller="MyCtrl">
      <h2>{{text}}</h2>
      <input type="text" ng-model="text"></input>
       <mydirective>
           <li><input type="text" ng-model="text"></input></li>
           <li>{{text}}</li>
      </mydirective>    
  </div>

JS:

angular.module('myApp', [])
.controller('MyCtrl',function($scope){
   $scope.text = 'Somestring'; 
})
.directive('mydirective', function () {
    return {
        restrict: 'E',
        transclude: true,
        scope: false, //do not create a new scope
        templateUrl: 'tmpl.html',
        replace: false,
        link : function(scope, element, attrs, ctrl, transclude){
            element.find("ul").append(transclude());
        }
    };
});

2 个答案:

答案 0 :(得分:1)

转换的工作原理是什么......这是无法阻止的......

问题是字符串是原始值,因此当您在子范围中更改它时,您将覆盖子范围,但不在父范围中更新。

有一篇关于范围的好文章:

https://github.com/angular/angular.js/wiki/Understanding-Scopes

要解决此问题 - 您可以创建对象以包装文本值:

$scope.data = {text: 'Something'};

http://codepen.io/anon/pen/bHpiF

解决此问题的另一种方法是使用子范围中的$parent

<mydirective>
     <li><input type="text" ng-model="$parent.text"></input></li>
     <li>{{$parent.text}}</li>
</mydirective>

http://codepen.io/anon/pen/stlcn

这取决于哪一个更好,但总的来说 - 我更喜欢第一个变体,在范围内避免原始价值。

答案 1 :(得分:1)

我实际上是自己找到了解决方案。有一种方法可以使用transclude(scope,fn)函数:

.directive('mydirective', function ($compile) {
    return {
        restrict: 'E',
        transclude: true,
        scope: false,
        templateUrl: 'tmpl.html',
        replace: false,
        link : function(scope, element, attrs, ctrl, transclude){
            transclude(scope,function(clone){
              $compile(clone)(scope).appendTo(element.find("ul"));
            });
        }
    };
});

请参阅更新后的示例here