使用transclude的AngularJS指令会破坏$ scope

时间:2015-03-23 04:19:46

标签: javascript angularjs angularjs-directive

我是AngularJS的新手。我尝试使用选项transclude=true创建指令,但似乎打破了$ scope。这是我的代码:

<!DOCTYPE html>
<html ng-app="myApp">
  <head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.15/angular.min.js"></script>
    <script type="text/javascript">
      var app = angular.module('myApp', []);

      app.controller('myController', ['$scope', function($scope){
        $scope.myText = 'Hello';

        $scope.facility = null;
        $scope.facilities = [
          {id:1, name:'One'},
          {id:2, name:'Two'},
          {id:3, name:'Three'}
        ];

        $scope.query = function(){
          console.log($scope.facility, $scope.myText);
        }
      }]);

      app.directive('ohMy', function(){
        return {
          transclude: true,
          template: function(){
            return '<form novalidate><div ng-transclude></div></form>';
          }
        }
      });

    </script>
  </head>
  <body>
    <div ng-controller="myController">
      <oh-my>
        <input type="text" ng-model="myText"></input>
        <div>{{myText}}</div>
        <select ng-change="query()" ng-model="facility" ng-options="f.name for f in facilities"></select>
      </oh-my>
    </div>
  </body>
</html>

当我更改文本框值(myText)时,文本框下一个div内的文本显示我预期的更新值。但是当我使用下拉菜单时 - 浏览器的控制台总是显示默认值。

当我删除此指令时,一切正常。

我在创建指令时做错了什么?有什么想法来解决它吗?

- 更新 -

谷歌搜索了一段时间后,我找到了这个链接:AngularJS transclude but keep the directive's scope并尝试理解它,然后我将指令代码修改为:

  app.directive('ohMy', function(){
    return {
      transclude: true,
      template: function(){
        return '<form novalidate><div ng-transclude></div></form>';
      },
      link: function(scope, element, attrs, ctrl, transclude) {
        transclude(scope, function(clone) {              
          element.children(0).empty().append(clone);
        });
      }
    }
  });

它正如我现在预期的那样工作。但是,还有更好的解决方案吗?

1 个答案:

答案 0 :(得分:-1)

您可以尝试从 $ parent 范围获取模型:

      <oh-my>
        <input type="text" ng-model="$parent.myText"></input>
        <div>{{myText}}</div>
        // get model from $parent scope.
        <select ng-change="query()" ng-model="$parent.facility" ng-options="f.name for f in $parent.facilities"></select>
      </oh-my>

链接演示:http://plnkr.co/edit/as7dSEybw7PWB24JlPWp?p=preview