【问题标题】:Binding data in a custom directive - AngularJS在自定义指令中绑定数据 - AngularJS
【发布时间】:2013-12-05 17:19:28
【问题描述】:

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

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

为了简化问题,我的小部件只是一个简单的文本输入。 当我尝试 $compile 小部件时,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 的新手,我的方法可能不是最好的,所以当然欢迎任何不同的想法!

【问题讨论】:

  • 你想实现什么不清楚
  • 在 Plunker 演示中,我希望将 2 个字段双向绑定到 $scope.resource.name

标签: angularjs data-binding


【解决方案1】:

由于您使用的是隔离作用域,所以一个问题是 resource 在父作用域上,并且在指令中不可见。而且我认为您正在寻找ng-model 而不是ng-bind

另外,既然你想绑定到namein resource,我们需要以某种方式绑定它。

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

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

Updated plunker

【讨论】:

  • 谢谢!你能解释一下 $parent 是什么意思吗?它只是指向当前的父范围吗?
【解决方案2】:

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

我的建议是使用“模板”更像是一个视图,这样操作更清晰。

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

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

ngModel 指令使用 NgModelController 将输入、选择、文本区域(或自定义表单控件)绑定到范围上的属性,该属性由该指令创建和公开。 [...]

更改指令:

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

编辑: 运维人员忘记了Updated Plunker

【讨论】:

  • 它更清晰,但我的主要目标是根据数据类型拥有不同的自定义小部件。是否可以根据 widgetType.type 有不同的模板?
  • @GuyB7 嗯,明白了。好吧,可以根据类型更改模板,但这将涉及在链接函数中使用 $http 和 $compile 来获取不同小部件 (like this dude suggests) 的 url,或者查看 ngInclude directive。对不起,如果它没有太大帮助,祝你好运!干杯。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-23
  • 2013-09-23
  • 2012-12-14
相关资源
最近更新 更多