2014-05-19 75 views
0

我想知道在angularjs中如何使用指令。我有几个页面有很多输入字段,每次我想添加一些条件ng-class和一个只在特定条件下显示的按钮。一个粗略的例子可以看出:使用angularjs中的指令模板

JSFiddle without directives

现在,我想少打字,希望指令能帮助我。下面的代码无法正常工作,但也许这显示了我想去的地方:

这就是我要输入我的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)

很明显,这是行不通的。我是否想做一些不可能的事情,或者我只是做错了什么?

回答

1

你非常接近!

一对夫妇的需要改变的东西:

  1. ngModel你必须参考的范围属性。
    相反的:ng-model="{{attr.editedObject}}.{{attr.attrName}}
    你应该是这样的:ng-model="attr.editedObject[attr.attrName]
    (意思是:“来绑定范围的attr属性其中x是引用名为x的对象的‘editedObject’属性引用的对象的属性。名称等于attr的'attrName'属性值的房产。“)
    是的,无论如何!

  2. 为了隔离范围能够访问实际编辑的对象(即personEdited),它需要对其进行引用。有几种方法可以实现这一点,但我认为最简单的方法是在firstnamelastname对象内引用它。例如为:
    相反的:$scope.firstName = {...editedObject: 'personEdited',...}
    用途:$scope.firstName = {...editedObject: $scope.personEdited,...}

还参见本short demo

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> 

,我们必将对我国指令的控制器,我们从指令中全面进入我们的控制器范围。我们不必创建隔离范围,我们可以简单地开始访问控制器的属性。

这里是什么,我猜你的目标是什么(根据您发布的小提琴)的例子的plunker:http://plnkr.co/edit/4AQkCSIJvqsrUOBOqway?p=preview

+0

我喜欢这样的做法,但我不能得到它的工作。你可以看看这个jsfiddle的错误:http://jsfiddle.net/ZyCdm/3/ – EasterBunnyBugSmasher

+0

我更新了我的答案上面:-) – pje

+0

对不起,这不是我真正想要的。正如我的jsfiddle示例所示,我想在一个Controller的范围内有多个输入字段。我的计划是像这样指定一个字段名称:并且不为每个字段名称创建一个Controller。 – EasterBunnyBugSmasher