【问题标题】:AngularJS directive using transclude breaks the $scope使用 transclude 的 AngularJS 指令破坏了 $scope
【发布时间】:2015-03-23 04:19:46
【问题描述】:

我是 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 内的文本显示更新后的值,正如我预期的那样。但不是当我使用下拉菜单时——浏览器的控制台总是显示默认值。

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

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

-- 更新--

google了一阵子,找到了这个链接: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);
        });
      }
    }
  });

它现在按我的预期工作。但是,有更好的解决方案吗?

【问题讨论】:

  • 是的,这是点规则。您的模型facility 应该嵌套在一个对象中。该指令创建了一个子范围,此时您正在使用两个不同的$scope.facility 属性,因为该值是一个原始值。如果你做foo.facility,子作用域将继承foo,然后facility必须是相同的。
  • 谢谢,m59!它与点一起工作。但正如你所说,这是“规则”,这是我们无法避免的吗?我的意思是这个指令中的模型必须是一个嵌套对象?
  • 有些人假装 $scope 继承不存在并在所有指令上放置隔离作用域,然后将数据显式传递给指令。

标签: javascript angularjs angularjs-directive


【解决方案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

【讨论】:

  • 谢谢,但没有 :) - 我不会更改 HTML 部分和控制器部分,我想修复指令。
猜你喜欢
  • 1970-01-01
  • 2016-10-03
  • 1970-01-01
  • 1970-01-01
  • 2015-05-04
  • 1970-01-01
  • 1970-01-01
  • 2017-11-19
  • 1970-01-01
相关资源
最近更新 更多