AngularJS: Transclusion创建新的作用域

AngularJS: Transclusion creates new scope

本文关键字:作用域 创建 Transclusion AngularJS      更新时间:2023-09-26

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

请在这里的例子。当第一个文本框被修改时,对文本的所有绑定都会更新,但是当跨包含的文本框被修改时,只会修改同一范围内的引用。在我的例子中,我希望这两个文本框更新所有引用文本

透入是否创建一个新的作用域?这种情况有办法预防吗?

示例代码:

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());
        }
    };
});

这就是transclude的工作方式…这是无法阻止的…

问题是字符串是原始值,所以当你在子作用域更改它时,你是在为子作用域重写它,而不是在父作用域更新它。

有一篇关于作用域的好文章:

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

这取决于哪一个更好,但一般来说-我更喜欢第一个变体,避免在作用域内的原始值

实际上我自己找到了解决方案。有一种方法是使用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"));
            });
        }
    };
});

查看此处更新的示例