2014-05-19 38 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