AngularJS指令数据绑定不起作用

时间:2014-10-07 22:30:20

标签: angularjs angularjs-directive angularjs-scope

DEMO

以下是我拥有的两个指令my-inputanother-directive的简化版本:

HTML:

<body ng-controller="AppCtrl">
  <another-directive>
    <my-input my-input-model="data.firstName"></my-input>
  </another-directive>
</body>

JS:

.directive('myInput', function() {
  return {
    restrict: 'E',
    replace: true,
    scope: {
      model: '=myInputModel'
    },
    template: '<input type="text" ng-model="model">'
  };
}).directive('anotherDirective', function($compile) {
  return {
    restrict: 'E',
    scope: {},
    compile: function(element) {
      var html = element.html();

      return function(scope) {
        var output = angular.element(
          '<div class="another-directive">' +
            html +
          '</div>'
        );

        $compile(output)(scope);
        element.empty().append(output); // This line breaks the binding
      };
    }
  };
});

正如您在demo中看到的,如果我删除element.empty().append(output);,一切正常,即输入字段中的更改会反映在控制器data中。但是,添加此行会破坏绑定。

为什么会这样?

PLAYGROUND HERE

3 个答案:

答案 0 :(得分:2)

element.empty()调用正在销毁element的所有子节点。在这种情况下,elementanother-directive的html表示形式。当你在它上面调用.empty()时,它正试图销毁它的子指令my-input以及随之而来的任何范围/数据绑定。

关于你的例子有点不相关的说明。您应该考虑使用transclusion将html嵌套在指令中,就像使用another-directive一样。您可以在此处找到更多信息:https://docs.angularjs.org/api/ng/service/ $ compile#transclusion

答案 1 :(得分:1)

我认为关于你要做的事情的一些背景是有帮助的。我假设您要将my-input指令包装在另一个指令(某种父窗格)中。您可以使用ng transclude来完成此操作。即

angular.module('App', []).controller('AppCtrl', function($scope) {
  $scope.data = {
    firstName: 'David'
  };
  $scope.test = "My test data";
}).directive('myInput', function() {
  return {
    restrict: 'E',
    replace: true,
    scope: {
      model: '=myInputModel'
    },
    template: '<input type="text" ng-model="model">'
  };
}).directive('anotherDirective', function($compile) {
  return {
    restrict: 'E',
    transclude: true,
    scope: {},
    template : '<div class="another-directive"><div ng-transclude></div></div>' 
    };
});

答案 2 :(得分:0)

如果您需要ngModel

,它会起作用
}).directive('anotherDirective', function($compile) {
return {
  restrict: 'E',
  require:'ngModel',
  scope: {},
...