我试图找出在angularjs中使用指令的位置和方法。我有几个页面有很多输入字段,每次我想添加一些条件ng-class和一个只在某些条件下显示的按钮。一个粗略的例子可以在:
现在我想减少输入并希望指令可以帮助我。以下代码不起作用,但它可能显示我想去的地方:
这就是我要输入我的html的方式:
<tr>
<td>First Name:</td>
<td>
<dirty-input attr="firstName"/>
</td>
</tr>
<tr>
<td>Last Name:</td>
<td>
<dirty-input attr="lastName"/>
</td>
</tr>
所以我尝试使用以下控制器完成此操作:
app.controller('PersonController', function($scope) {
$scope.person = {firstName: 'John', lastName: 'Doe'};
$scope.personEdited = {firstName: $scope.person.firstName, lastName: $scope.person.lastName};
$scope.firstName = {objName: 'person', editedObject: 'personEdited', attrName: 'firstName'};
$scope.lastName = {objName: 'person', editedObject: 'personEdited', attrName: 'lastName'};
});
和这个指令:
app.directive('dirtyInput', function() {
return {
restrict: 'E',
scope: {
attr: '=attr',
},
template: '<input type="text" ng-model="{{attr.editedObject}}.{{attr.attrName}}"/>'
};
});
可以在JSFiddle with directives (not working)
看到显然,这不起作用。我是在尝试做一些不可能的事情,还是我做错了?
答案 0 :(得分:1)
你非常接近!
需要改变的一些事情:
在ngModel
上,你必须引用范围内的财产
而不是:ng-model="{{attr.editedObject}}.{{attr.attrName}}
你应该有:ng-model="attr.editedObject[attr.attrName]
(这意味着:&#34;绑定到由范围&#39; s attr
属性引用的对象的&edit;&#39;属性引用的对象的名为x的属性。其中x是名称等于attr
&#39; s&#39; attrName&#39;属性值的属性。&#34;)
是的,无论如何!
为了使隔离范围能够访问实际编辑的对象(即personEdited
),它需要对它进行引用。有几种方法可以实现这一点,但我认为最简单的方法是在firstname
,lastname
对象中引用它。例如: -
而不是:$scope.firstName = {...editedObject: 'personEdited',...}
使用:$scope.firstName = {...editedObject: $scope.personEdited,...}
另请参阅此 short demo 。
答案 1 :(得分:0)
您误解了隔离范围的工作原理。您的指令模板正在尝试访问其隔离范围上的{{attr.editedObject}}.{{attr.attrName}}
。我们假设角度将{{attr.editedObject}}.{{attr.attrName}}
解析为personEdited.firstName
。现在考虑隔离范围,它目前由单个属性attr
组成。当您的指令解析personEdited.firstName
时,它会查看其隔离范围,并且只能看到attr
。因为personEdited
未定义,所以没有任何反应。为了使其工作,您必须在隔离范围中包含另一个属性,该属性在控制器范围上分配了personEdited的值。该属性需要命名为personEdited
:
scope: {
attr: '=attr',
personEdited: '=personEdited'
}
然后你需要在你的指令用法中分配它:
<dirty-input attr="firstName" personEdited="personEdited" />
现在,您的隔离范围可以访问personEdited
中定义的PersonController
对象。希望这会有所帮助。
修改强>
在考虑了这一点之后,您可能想要在指令中尝试控制器。根据我的猜测,根据您的问题,您真正想要的是访问PersonController
的范围。您可以在指令中使用以下语法完成此操作:
myApp.directive('myDirtyInput', function () {
return {
restrict: 'E',
replace: true,
templateUrl: 'DirtyInput.html',
controller: '@',
name: 'ctrl'
};
});
这里要注意的两件事是控制器属性和名称属性。这些告诉角度js的是我们将允许我们的指令的用户绑定一个控制器供我们使用,它将通过在指令声明中定义ctrl
属性来分配。所以在我们的例子中,这将是:
<my-dirty-input ctrl="PersonController"></my-dirty-input>
现在,我们的控制器绑定到我们的指令,我们可以从指令中完全访问我们的控制器范围。我们不必创建隔离范围,我们可以简单地开始访问控制器的属性。
这是一个有关我猜想你想做的事情的例子(根据你发布的小提琴):http://plnkr.co/edit/4AQkCSIJvqsrUOBOqway?p=preview