在自定义指令中绑定数据 - AngularJS

时间:2013-12-05 17:19:28

标签: angularjs data-binding

我有一个自定义指令,其目的是呈现一个小部件并将其绑定到一个变量。 每个变量都有不同的数据类型,因此将根据数据类型显示不同的小部件。

我的问题是我可以传递变量的数据,但我无法将窗口小部件绑定到它。

为了简化问题,我的小部件只是一个简单的文本输入。 当我尝试$编译窗口小部件时,Angular使用变量的值而不是绑定它。

HTML:

<body ng-app="app" ng-controller="myCtrl">
  <input type="text" ng-model="resource.name"></div>
  <div custom-widget widget-type="widget" bind-to="resource"></div>
</body>

使用Javascript:

angular.module('app', [])
  .directive('customWidget', function($compile) {
    return {
      replace: true,
      template: '<div></div>',
      controller: function($scope) {

      },
      scope: {
        bindTo: "=bindTo",
        widgetType: "=widgetType"
      },
      link: function(scope, iElem, iAttrs) {
        var html = '<div>' + scope.widgetType.label + ':<input ng-bind="' + scope.bindTo[scope.widgetType.id] + '" /></div>';
        iElem.replaceWith($compile(html)(scope));
      }
    };
  })
  .controller('myCtrl', function($scope) {
    $scope.widget = {
      id: 'name',
      label: 'Text input',
      type: 'text'
    };
    $scope.resource = {
      name: 'John'
    };
  });

Plunker演示:http://plnkr.co/edit/qhUdNhjSN7NlP4xRVcEA?p=preview

我还是AngularJS的新手,我的方法可能不是最好的,所以任何不同的想法当然都会受到赞赏!

2 个答案:

答案 0 :(得分:1)

由于您正在使用隔离范围,因此resource位于父范围内且在指令中不可见。我认为您正在寻找ng-model而不是ng-bind

此外,由于您要绑定到name中的resource,我们需要以某种方式将其绑定。

所以这里是你的模板html的一种方法(请注意添加$parent以解决范围问题和添加.name(如果您愿意,可以使用变量以编程方式添加,或者将其指定为属性的一部分))

var html = '<div>' + scope.widgetType.label + ':<input ng-model="' + '$parent.' + iAttrs.bindTo +'.name'+ '" /></div>';

Updated plunker

答案 1 :(得分:0)

好吧,当你的指令中有一个孤立的范围并使用“=”运算符时,你已经有了双向数据绑定。

我的建议是将“模板”更像是一个视图,以便操作更清晰。

我会将您的指令更改为以下内容:

使用ng-model而不是ng-bing主要是因为Documentation显示:

  

ngModel指令使用NgModelController将输入,select,textarea(或自定义表单控件)绑定到作用域上的属性,该指令由此指令创建和公开。 [...]

更改指令:

angular.module('app', [])
  .directive('customWidget', function($compile) {
    return {
      replace: true,
      template: '<div> {{widgetType.label}} <input ng-model="bindTo[widgetType.id]" /></div>',
      scope: {
        bindTo: "=bindTo",
        widgetType: "=widgetType"
      }
   };
 });

编辑: Ops忘记了Updated Plunker