我有一个自定义指令,其目的是呈现一个小部件并将其绑定到一个变量。 每个变量都有不同的数据类型,因此将根据数据类型显示不同的小部件。
我的问题是我可以传递变量的数据,但我无法将窗口小部件绑定到它。
为了简化问题,我的小部件只是一个简单的文本输入。 当我尝试$编译窗口小部件时,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的新手,我的方法可能不是最好的,所以任何不同的想法当然都会受到赞赏!
答案 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>';
答案 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