0

我正在處理幾個組件(指令)以幫助進行表單驗證。我希望組件知道相關輸入元素的狀態(如需要)。例如...直接從form.FormController訪問表單元素?

標記:

<form name="editUser"> 
    <control-label input="editUser.name">Name</control-label> 
    <input type="text" name="name" ng-model="user.name" required/> 
</form> 

指令:

app.directive("controlLabel", function() { 
    return { 
    restrict: "E", 
    replace: true, 
    transclude: true, 
    scope: { 
     input: "=input" 
    }, 
    template: 
     '<label class="control-label">'+ 
     '<span ng-transclude>{{label}}</span>'+ 
     '<span ng-if="input.required"> (required!)</span>'+ // doesn't work? 
     '</label>' 
    }; 
}); 

輸出:

<form name="editUser"> 
    <label> 
     <span>Name</span> 
     <span>(required!)</span> 
    </label> 
    <input type="text" name="name" ng-model="user.name" required/> 
</form> 

源因爲form.FormController讓我相信這是不可能的。有什麼辦法可以至少訪問元素上的attrs?我想過使用裝飾器,但到目前爲止,我還沒有弄清楚如何完成這件事。

回答

1

您應該使用input.$validators.required代替input.required爲:

myApp.directive("controlLabel", function() { 
    return { 
    restrict: "E", 
    replace: true, 
    transclude: true, 
    scope: { 
     input: "=input" 
    }, 
    template: 
     '<label class="control-label">'+ 
     '<span ng-transclude>{{label}}</span>'+ 
     '<span ng-if="input.$validators.required"> (required!)</span>'+ 
     '</label>' 
    }; 
}); 

Working Demo

+0

我需要編輯標誌始終顯示,而不僅僅是$ error – Brian

+0

@Brian:然後使用'input。$ validators.required'。更新了上面的答案。 – codef0rmer

+1

謝謝@ codeF0rmer,這正是我正在尋找的。甚至不知道存在$驗證器:P – Brian

1

首先,您的代碼存在錯誤。如果您使用的是transclude,則必須在您的指令中聲明它,否則會出現錯誤。

至於你的問題,在一個指令中,你可以訪問DOM元素。而對於這個特殊的使用情況下,你甚至可以在沒有所有的人創造孤立的範圍或附加屬性獲得通過:

app.directive("controlLabel", function() { 
    return { 
     restrict: "E", 
     replace: true, 
     scope: true,  // if needed, can also use empty isolated scope { } 
     transclude: true, // must declare this 
     template: 
       '<label class="control-label">' + 
       '<span ng-transclude>{{label}}</span>' + 
       '<span ng-if="show"> (required!)</span>' + 
       '</label>', 
     link: function(scope, jqElem, attrs) { 
      // check if next sibling of this directive is required 
      scope.show = (jqElem.next().attr("required") === 'required'); 
     } 
    }; 
}); 

現在你的控制標籤實在是最小的,並且DRY,邏輯是指令中以及封裝。唯一的要求是,你directive目標必須在標籤的下一個兄弟:

<control-label>Name</control-label> 
<input type="text" name="name" ng-model="user.name" required/> 

當然,如果需要的話,你可以用你的jquery-FU改變link功能,以滿足您的其他要求。

+0

感謝@ b0nyb0y。我想我也可以使用的#id來捕獲它的相關

+0

@Brian啊,你說的範圍問題是對的,我的不好。沒有聲明'範圍',每個輸入將在整個控制器下共享相同的'show'值。所以我猜在這種情況下,你可以** a)**聲明'scope:true'(創建子範圍),或者** b)**'scope:{}'(創建隔離範圍)。您的選擇取決於您是否要在指令作用域中繼承父變量。我現在要解決這個問題。 – b0nyb0y